我在同一个控制器上有两个操作,路由相同,但Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
snmp.getUSM().addUser(securityName, new UsmUser(securityName,
authProtocol,
authPassphrase,
privProtocol,
privPassphrase));
个要求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
时,两个端点都能正常工作。
E.g。
POST
如果我将操作分成单独的控制器,它就不再起作用了:
DELETE /api/test = endpoint1
POST /api/test = endpoint2
E.g。
[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");
}
}
这是从框架预期的吗?
修改 确切的WebAPI包版本是:5.2.3
答案 0 :(得分:6)
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件事
1.路由属性和路由模板
2.对路径应用动词路由约束
3.指定操作方法选择器,因此系统的其余部分(如帮助页面)就像[HttpPost]
/ [HttpDelete]
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");
}
}
答案 1 :(得分:0)
[HttpDelete(“ DeleteEmployee / {id}”)] 公共异步任务DeleteEmployee(Guid id)