c# – WebAPI 2.0发布和删除路由
我在同一个控制器上有两个动作,具有相同的路由,但是单独的HttpMethod要求(POST与DELETE).
[AllowAnonymous] public class TestController : ApiController { [Route("~/api/test")] [HttpDelete] public IHttpActionResult Endpoint1() { return this.Ok("endpoint1"); } [Route("~/api/test")] [HttpPost] public IHttpActionResult Endpoint2() { return this.Ok("endpoint2"); } } 这一切都很好 – 从DELETE切换到POST时,两个端点都有效. 例如. DELETE /api/test = endpoint1 POST /api/test = endpoint2 如果我将操作分成单独的控制器,它就不再起作用了: [AllowAnonymous] public class TestController : ApiController { [Route("~/api/test")] [HttpDelete] public IHttpActionResult Endpoint1() { return this.Ok("endpoint1"); } } [AllowAnonymous] public class TestController2 : ApiController { [Route("~/api/test")] [HttpPost] public IHttpActionResult Endpoint2() { return this.Ok("endpoint2"); } } 例如. DELETE /api/test = endpoint1 POST /api/test = { "Message": "The requested resource does not support http method 'POST'." } 这是从框架中预期的吗? 编辑: 解决方法
到底是怎么回事
Web API 2.0不允许在两个不同的控制器上匹配路由.这在MVC 6(Web API组合框架)中得到了解决. 我该怎么办呢 首先像@woogy,你说,它不是一个非常常见的模式,因此大多数用户不应该去这里(或者当它进入RTM时转移到MVC 6). 根本原因是路由实际匹配,动词定义了一个IActionHttpMethodProvider不约束匹配的路由,并且它匹配多个控制器因此失败. 但是,您可以在路线上定义约束,并且作为副作用可以获得更简洁的API. 让我们开始吧 定义动词约束 这将限制路径仅匹配预定义的动词,因此它与其他控制器不匹配. public class VerbConstraint : IHttpRouteConstraint { private HttpMethod _method; public VerbConstraint(HttpMethod method) { _method = method; } public bool Match(HttpRequestMessage request,IHttpRoute route,string parameterName,IDictionary<string,object> values,HttpRouteDirection routeDirection) { // Note - we only want to constraint on the outgoing path if (routeDirection == HttpRouteDirection.UriGeneration || request.Method == _method) { return true; } return false; } } 为新属性定义抽象基类 public abstract class VerbRouteAttribute : RouteFactoryAttribute,IActionHttpMethodProvider { private string _template; private HttpMethod _method; public VerbRouteAttribute(string template,string verb) : base(template) { _method = new HttpMethod(verb); } public Collection<HttpMethod> HttpMethods { get { var methods = new Collection<HttpMethod>(); methods.Add(_method); return methods; } } public override IDictionary<string,object> Constraints { get { var constraints = new HttpRouteValueDictionary(); constraints.Add("verb",new VerbConstraint(_method)); return constraints; } } } 这个类合并了3件事 现在让我们定义实现 public class PostRouteAttribute : VerbRouteAttribute { public PostRouteAttribute(string template) : base(template,"POST") { } } public class DeleteRouteAttribute : VerbRouteAttribute { public DeleteRouteAttribute(string template) : base(template,"DELETE") { } } 您可以告诉它们非常简单,只需在代码中使用这些属性就可以更加顺畅. 最后让我们应用新属性(并删除方法属性) [AllowAnonymous] public class TestController : ApiController { [DeleteRoute("api/test")] public IHttpActionResult Endpoint1() { return this.Ok("endpoint1"); } } [AllowAnonymous] public class TestController2 : ApiController { [PostRoute("api/test")] public IHttpActionResult Endpoint2() { return this.Ok("endpoint2"); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |