6

我正在尝试在 OData v4 Web API 解决方案中创建自定义函数。我需要根据 OData 无法本地处理的独特逻辑返回一组“订单”。我似乎无法弄清楚如何在不破坏整个 OData 服务层的情况下创建这个自定义函数。当我用 ODataRoute 属性装饰 Controller 方法时,一切都变了。任何基本请求都会产生相同的错误。有人可以看看下面的代码,看看你是否注意到我必须遗漏的东西?

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 层发出 ANY 请求时,我收到以下错误响应。

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

4

1 回答 1

5

根据模型构建器,函数 GetByExternalKey 是一个绑定函数。根据OData Protocol v4,绑定函数是通过namespace或者aliasqualified named来调用的,所以需要在route属性中添加更多:

[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 类型的命名空间。

以下是与您的问题相关的 2 个示例,仅供您参考: https ://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataFunctionSample/

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

于 2014-08-12T23:54:37.200 回答