OData:自定义操作永远不起作用

OData: Custom Action never works

我快疯了。我尝试了很多通过网络找到的不同方法。但是似乎无法完成这项工作。这是我尝试的最后一件事。

modelBuilder.EntitySet<User>("Users").EntityType.Action("IsEmailAvailable")
.Returns<bool>()
.Parameter<string>("email");

我这样配置我的实体。

[HttpPost]
public bool IsEmailAvailable(ODataActionParameters parameters)
{
    return true;
}

这是我控制器中的动作。

当我做类似

的事情时

http://localhost:11111/odata/Users

我得到了预期的实体。但是如果我这样做

http://localhost:11111/odata/Users/IsEmailAvailable

我收到错误:

Message: "The OData path is invalid.", ExceptionMessage: "Invalid action detected. 'IsEmailAvaliable' is not an action that can bind to 'Collection([App.Models.Models.User Nullable=False])'.", ExceptionType: "Microsoft.Data.OData.ODataException", StackTrace: " at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment) at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment) at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseNextSegment(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment) at System.Web.Http.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String odataPath) at System.Web.Http.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)"

埃格

下面的错误信息很有意义。它告诉 "IsEmailAvaliable" 可以与 Collection 一起调用。

IsEmailAvaliable' is not an action that can bind to 'Collection([App.Models.Models.User Nullable=False])'

来自您的模型构建代码:

modelBuilder.EntitySet<User>("Users").EntityType.Action("IsEmailAvailable")
.Returns<bool>()
.Parameter<string>("email");

您定义 IsEmailAvailable 绑定到 User 类型,而不是 User 类型的集合。

有两种方法可以让它工作:

  1. 保持模型构建代码不变,但您应该将其命名为:

    http://localhost:11111/odata/Users(key)/Namespace.IsEmailAvailable

  2. 将模型构建代码修改为:

    modelBuilder.EntitySet("Users").EntityType.Collection.Action("IsEmailAvailable") .Returns() .参数("email");

注意:我在调用Action之前添加了Collection。然后你可以称它为:

http://localhost:11111/odata/Users/Namespace.IsEmailAvailable

注意:如果使用OData V4相关库,则需要Namespace

我在 my sample project, it should work. See my newest commit.

测试过

WebApiConfig.cs 中,我添加了两个使用与您类似的代码的操作:

builder.EntitySet<Customer>("Customers")
    .EntityType.Collection.Action("IsEmailAvailable")
    .Returns<bool>()
    .Parameter<string>("email");

builder.EntitySet<Customer>("Customers")
    .EntityType.Action("IsEmailAvailable").Returns<bool>()
    .Parameter<string>("email");

其中,

  1. 第一个绑定到 collection 实体类型。
  2. 第二个绑定到实体类型。

CustomersController中有两种方法:

[HttpPost]
public bool IsEmailAvailable(ODataActionParameters parameters)
{
    ...
}

[HttpPost]
public IHttpActionResult IsEmailAvailable(int key, ODataActionParameters parameters)
{
    ...
}

其中,

  1. 绑定到 collection 实体类型的操作将路由到第一个方法。
  2. 绑定到实体类型的操作将路由到第二个方法。

具体实现请参考我的项目

测试

绑定到collection

  1. Return "True"

要求:

POST http://localhost:33082/odata/Customers/Extra.IsEmailAvailable
Content-Type: application/json
Content: 
{"email":"saxu@microsoft.com"}

回复:

{
  "@odata.context":"http://localhost:33082/odata/$metadata#Edm.Boolean","value":true
}
  1. Return "False"

要求:

POST http://localhost:33082/odata/Customers/Extra.IsEmailAvailable
Content-Type: application/json
Content: 
{"email":"abc@microsoft.com"}

回复:

{
  "@odata.context":"http://localhost:33082/odata/$metadata#Edm.Boolean","value":false
}

绑定到实体类型

  1. Return NotFound(在我的实现中,我硬设置了键必须是“3”,否则,它returns "NotFound (404)"

要求:

POST http://localhost:33082/odata/Customers(2)/Extra.IsEmailAvailable
Content-Type: application/json
Content: 
{"email":"saxu@microsoft.com"}

回复:

HTTP/1.1 404 Not Found
  1. Return 一个字符串(在我的实现中,如果密钥是 3,我很难 return 一个字符串,并且电子邮件是 "saxu@microsoft.com")

要求:

POST http://localhost:33082/odata/Customers(3)/Extra.IsEmailAvailable
Content-Type: application/json
Content: 
{"email":"saxu@microsoft.com"}

回复:

{
  "@odata.context":"http://localhost:33082/odata/$metadata#Edm.String","value":"Your input email is :saxu@microsoft.com"
}
  1. Return 错误。类似的,省略。

另外还有几个资料可以参考:

  1. http://blogs.msdn.com/b/odatateam/archive/2014/12/08/function-amp-action-in-web-api-v2-2-for-odata-v4-0-type-scenario.aspx
  2. http://odata.github.io/WebApi/#04-07-action-parameter-support

希望对您有所帮助。谢谢。

好吧,冷静下来后,因为我疯了为什么这不起作用,我开始思考并找到问题的原因。我不知何故安装了 Odata 的 V1-3 和 V4 版本。所以当我使用构建器时,它变得很困惑。所以我卸载了 V1-3 并修复了编译器错误,它工作正常。感谢 Sam Xu 的努力。