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;
}
这是我控制器中的动作。
当我做类似
的事情时
我得到了预期的实体。但是如果我这样做
我收到错误:
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
类型的集合。
有两种方法可以让它工作:
保持模型构建代码不变,但您应该将其命名为:
http://localhost:11111/odata/Users(key)/Namespace.IsEmailAvailable
将模型构建代码修改为:
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");
其中,
- 第一个绑定到 collection 实体类型。
- 第二个绑定到实体类型。
在CustomersController
中有两种方法:
[HttpPost]
public bool IsEmailAvailable(ODataActionParameters parameters)
{
...
}
[HttpPost]
public IHttpActionResult IsEmailAvailable(int key, ODataActionParameters parameters)
{
...
}
其中,
- 绑定到 collection 实体类型的操作将路由到第一个方法。
- 绑定到实体类型的操作将路由到第二个方法。
具体实现请参考我的项目
测试
绑定到collection
- 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
}
- 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
}
绑定到实体类型
- 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
- 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"
}
- Return 错误。类似的,省略。
另外还有几个资料可以参考:
- 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
- http://odata.github.io/WebApi/#04-07-action-parameter-support
希望对您有所帮助。谢谢。
好吧,冷静下来后,因为我疯了为什么这不起作用,我开始思考并找到问题的原因。我不知何故安装了 Odata 的 V1-3 和 V4 版本。所以当我使用构建器时,它变得很困惑。所以我卸载了 V1-3 并修复了编译器错误,它工作正常。感谢 Sam Xu 的努力。
我快疯了。我尝试了很多通过网络找到的不同方法。但是似乎无法完成这项工作。这是我尝试的最后一件事。
modelBuilder.EntitySet<User>("Users").EntityType.Action("IsEmailAvailable")
.Returns<bool>()
.Parameter<string>("email");
我这样配置我的实体。
[HttpPost]
public bool IsEmailAvailable(ODataActionParameters parameters)
{
return true;
}
这是我控制器中的动作。
当我做类似
的事情时我得到了预期的实体。但是如果我这样做
我收到错误:
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
类型的集合。
有两种方法可以让它工作:
保持模型构建代码不变,但您应该将其命名为:
http://localhost:11111/odata/Users(key)/Namespace.IsEmailAvailable
将模型构建代码修改为:
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");
其中,
- 第一个绑定到 collection 实体类型。
- 第二个绑定到实体类型。
在CustomersController
中有两种方法:
[HttpPost]
public bool IsEmailAvailable(ODataActionParameters parameters)
{
...
}
[HttpPost]
public IHttpActionResult IsEmailAvailable(int key, ODataActionParameters parameters)
{
...
}
其中,
- 绑定到 collection 实体类型的操作将路由到第一个方法。
- 绑定到实体类型的操作将路由到第二个方法。
具体实现请参考我的项目
测试
绑定到collection
- 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
}
- 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
}
绑定到实体类型
- 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
- 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"
}
- Return 错误。类似的,省略。
另外还有几个资料可以参考:
- 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
- http://odata.github.io/WebApi/#04-07-action-parameter-support
希望对您有所帮助。谢谢。
好吧,冷静下来后,因为我疯了为什么这不起作用,我开始思考并找到问题的原因。我不知何故安装了 Odata 的 V1-3 和 V4 版本。所以当我使用构建器时,它变得很困惑。所以我卸载了 V1-3 并修复了编译器错误,它工作正常。感谢 Sam Xu 的努力。