OData:自定义操作永远不会有效

时间:2015-07-12 03:13:33

标签: c# api routing odata

我在这里变得疯狂。我尝试了很多不同的方法,我通过网络找到了。但似乎无法得到这项工作。这是我尝试的最后一件事。

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

我收到了错误:

  

消息:&#34; OData路径无效。&#34;,ExceptionMessage:&#34;无效   检测到行动。 &#39; IsEmailAvaliable&#39;不是可以绑定的动作   &#39; Collection([App.Models.Models.User Nullable = False])&#39;。&#34;,   ExceptionType:&#34; Microsoft.Data.OData.ODataException&#34;,StackTrace:&#34;在   System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtEntityCollection(IEdmModel   model,ODataPathSegment previous,IEdmType previousEdmType,String   段)   System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtCollection(IEdmModel   model,ODataPathSegment previous,IEdmType previousEdmType,String   段)   System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseNextSegment(IEdmModel   model,ODataPathSegment previous,IEdmType previousEdmType,String   段)   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)&#34;

3 个答案:

答案 0 :(得分:3)

我在my sample project进行了测试,它应该可行。查看我的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. 第一个绑定到实体类型的集合。
  2. 第二个绑定到实体类型。
  3. CustomersController中,有两种方法:

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

    哪里

    1. 绑定到实体类型集合的操作将路由到第一个方法。
    2. 绑定到实体类型的操作将路由到第二种方法。
    3. 有关详细实施,请参阅我的项目。

      测试

      绑定到集合

      1. 返回&#34; True&#34;
      2. 请求:

        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. 返回&#34;错误&#34;
        2. 请求:

          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. 返回NotFound(在我的实施中,我知道密钥必须是&#34; 3&#34;否则,它返回&#34; NotFound(404)&#34;
          2. 请求:

            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. 返回一个字符串(在我的实现中,如果键为3,我很难返回一个字符串,电子邮件是&#34; saxu@microsoft.com")
            2. 请求:

              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. 返回错误。它类似,省略它。
              2. 此外,您可以参考以下几种材料:

                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
                3. 希望它可以帮到你。感谢。

答案 1 :(得分:1)

埃格

以下错误消息很有意义。它告诉&#34; IsEmailAvaliable&#34;可以与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(&#34;用户&#34)。EntityType.Collection.Action(&#34; IsEmailAvailable&#34) .Returns() 。参数(&#34;电子邮件&#34);

  3. 注意:我在致电Collection之前添加Action。然后你可以把它称为:

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

    注意:如果您使用的是与OData V4相关的库,则必须使用Namespace

答案 2 :(得分:1)

好吧,好吧,平静下来,因为我疯了为什么这不起作用,我开始思考并找到问题的原因。不知怎的,我安装了Odata的V1-3和V4版本。因此,当我使用构建器时,它变得混乱。所以我取消了V1-3并修复了编译器错误,并且工作正常。感谢Sam Xu的努力。