对于同一HttpVerb多个动作(Multiple actions for the same Htt

2019-08-02 01:48发布

我有以下操作一个Web API控制器:

    [HttpPut]
    public string Put(int id, JObject data)

    [HttpPut, ActionName("Lock")]
    public bool Lock(int id)

    [HttpPut, ActionName("Unlock")]
    public bool Unlock(int id)

而下面的路线映射:

        routes.MapHttpRoute(
            name: "Api",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        routes.MapHttpRoute(
            name: "ApiAction",
            routeTemplate: "api/{controller}/{action}/{id}"
        );

当我提出以下要求一切正常:

PUT /api/items/Lock/5
PUT /api/items/Unlock/5

但是,当我试图做一个请求:

PUT /api/items/5

我得到以下异常:

Multiple actions were found that match the request:
    Put(int id, JObject data)
    Lock(int id)
    Unlock(int id)

我尝试添加一个空的动作名称默认路由,但没有帮助:

[HttpPut, ActionName("")]
public string Put(int id, JObject data)

任何想法如何,我可以用自定义动作的名称结合REST风格的默认路由?

编辑:路由机制不是由控制器的选择迷茫。 它是由一个行动控制器上的选择困惑。 我需要的是指定的任何操作时相匹配的默认操作。 希望澄清的事情。

Answer 1:

这是默认操作选择这是一个预期的错误ApiControllerActionSelector 。 你基本上有三种操作方法对应于HTTP Put动词。 也请记住,默认的动作选择认为这些都是原始的.NET类型简单的动作参数类型,知名的简单类型( System.StringSystem.DateTimeSystem.DecimalSystem.GuidSystem.DateTimeOffsetSystem.TimeSpan )和底层简单类型(例如: Nullable<System.Int32>

作为解决您的问题,我会创建两个控制器,为那些如下:

public class FooController : ApiController { 

    public string Put(int id, JObject data)
}

public class FooRPCController : ApiController { 

    [HttpPut]
    public bool Lock(int id)

    [HttpPut]
    public bool Unlock(int id)
}

路线看起来像如下:

routes.MapHttpRoute(
    name: "ApiAction",
    routeTemplate: "api/Foo/{action}/{id}",
    defaults: new { controller = "FooRPC" }
);

routes.MapHttpRoute(
    name: "Api",
    routeTemplate: "api/Foo/{id}",
    defaults: new { id = RouteParameter.Optional, controller = "Foo" }
);

在另一方面(未完全与主题相关的),我对动作选择3篇博客文章,特别是复合型的参数。 我建议你检查出来,因为他们可以给你几个观点:

  • 复合型操作参数和控制器动作选择与ASP.NET的Web API
  • 复合型操作参数处理ASP.NET Web API ComplexTypeAwareActionSelector -第1部分
  • 复合型操作参数处理ASP.NET Web API ComplexTypeAwareActionSelector -第2部分


Answer 2:

的帮助下吉斯卡尔Biamby ,我发现这个答案 ,其指出我朝着正确的方向发展。 最后,要解决这个具体的问题,我就是这么做的:

routes.MapHttpRoute(
    name: "ApiPut", 
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Put" }, 
    constraints: new { httpMethod = new HttpMethodConstraint("Put") }
);

由于@GiscardBiamby



Answer 3:

首先,删除[HttpPut, ActionName("")] ,然后修改你的路线,这

config.Routes.MapHttpRoute(
    name: "Api",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional },
    constraints: new { id = @"^[0-9]+$" }
    );  


文章来源: Multiple actions for the same HttpVerb