OData v4自定义函数

6
我正在尝试在OData v4 Web API解决方案中创建自定义函数。 根据无法由OData本身处理的独特逻辑,我需要返回一个“Orders”集合。 我似乎无法在不破坏整个OData服务层的情况下创建此自定义功能。 当我使用ODataRoute属性装饰控制器方法时,一切都变得混乱。 任何基本请求都会产生相同的错误。 请有人查看下面的代码,并看看您是否注意到我可能遗漏了什么?
WebApiConfig.cs
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.MapODataServiceRoute("odata", "odata", model: GetModel());
    }

    public static Microsoft.OData.Edm.IEdmModel GetModel()
    {
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Account>("Accounts");
        builder.EntitySet<Email>("Emails");
        builder.EntitySet<PhoneNumber>("PhoneNumbers");
        builder.EntitySet<Account>("Accounts");
        builder.EntitySet<Address>("Addresses");
        builder.EntitySet<Order>("Orders");
        builder.EntitySet<OrderDetail>("OrderDetails");

        var orders = builder.EntityType<Order>();
        var function = orders.Function("GetByExternalKey");
        function.Parameter<long>("key");
        function.ReturnsCollectionFromEntitySet<Order>("Orders");

        return builder.GetEdmModel();
     }
 }

OrdersController.cs

public class OrdersController : ODataController
{
    private SomeContext db = new SomeContext();

    ...Other Stuff...

    [HttpGet]
    [ODataRoute("GetByExternalKey(key={key})")]
    public IHttpActionResult GetByExternalKey(long key)
    {
       return Ok(from o in db.Orders
          where //SpecialCrazyStuff is done
          select o);
    }
}
}

在对OData层发出任何请求时,我收到以下错误响应。

控制器“Orders”中操作“GetByExternalKey”的路径模板'GetByExternalKey(key={key})'不是有效的OData路径模板。资源未找到段'GetByExternalKey'。


我曾经遇到过类似的问题。在添加自定义函数时,我收到了相同的错误。我能够使用自定义函数启动一个干净的项目,并且它正常工作,但是在添加了另一个控制器后,就会收到上面的错误。发现解决方案和解释在这里:Adding a new OData controller fails existing controller - Pynt
1个回答

5

根据模型构建器,GetByExternalKey函数是一个绑定函数。根据OData协议v4,绑定函数通过命名空间或别名限定名称调用,因此您需要在路由属性中添加更多内容:

[HttpGet]
[ODataRoute("Orders({id})/Your.Namespace.GetByExternalKey(key={key})")]
public IHttpActionResult GetByExternalKey(long key)
{
   return Ok(from o in db.Orders
      where//SpecialCrazyStuff is done
      select o);
}

如果你不知道名称空间,只需在 GetModel() 方法中添加以下内容:

builder.Namespace = typeof(Order).Namespace;

将“Your.Namespace”替换为类型Order的命名空间。

这里有两个与您问题相关的示例,仅供参考: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataFunctionSample/

https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataAttributeRoutingSample/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接