【发布时间】:2012-06-10 19:31:59
【问题描述】:
我正在寻找这个问题的答案,发现this question,确实非常相似。但是,那里发布的解决方案似乎对我不起作用......我想知道这是否与问题的年龄有关。
给定以下网址:
/my/items/6
我希望此 URL 的 HTTP PUT 请求由一种操作方法处理,而 HTTP DELETE 请求由另一种操作方法处理。下面是我定义的路线(注意这些路线是基于一个区域,所以context 是一个AreaRegistrationContext 实例,如果这很重要的话):
context.MapRoute(null,
"my/items/{id}",
new { area = "AreaName", controller = "ControllerName", action = "Replace" },
new
{
httpMethod = new HttpMethodConstraint("POST", "PUT"),
}
);
context.MapRoute(null,
"my/items/{id}",
new { area = "AreaName", controller = "ControllerName", action = "Destroy" },
new
{
httpMethod = new HttpMethodConstraint("POST", "DELETE"),
}
);
URL 生成适用于这两种路由,但是在路由传入请求时会出现问题。只有第一个声明的路由正确映射到其各自的操作。
我挖掘了HttpMethodConstraint源代码,发现它不关心"X-HTTP-Method-Override"参数,只关心HttpContext.Request.HttpMethod。
我能够使用以下自定义路由约束类解决此问题:
public class HttpMethodOverrideConstraint : HttpMethodConstraint
{
public HttpMethodOverrideConstraint(params string[] allowedMethods)
: base(allowedMethods) { }
protected override bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
var methodOverride = httpContext.Request
.Unvalidated().Form["X-HTTP-Method-Override"];
if (methodOverride == null)
return base.Match(httpContext, route, parameterName,
values, routeDirection);
return
AllowedMethods.Any(m =>
string.Equals(m, httpContext.Request.HttpMethod,
StringComparison.OrdinalIgnoreCase))
&&
AllowedMethods.Any(m =>
string.Equals(m, methodOverride,
StringComparison.OrdinalIgnoreCase))
;
}
}
...以及这些路由定义:
context.MapRoute(null,
"my/items/{id}",
new { area = "AreaName", controller = "ControllerName", action = "Replace" },
new
{
httpMethod = new HttpMethodOverrideConstraint("POST", "PUT"),
}
);
context.MapRoute(null,
"my/items/{id}",
new { area = "AreaName", controller = "ControllerName", action = "Destroy" },
new
{
httpMethod = new HttpMethodOverrideConstraint("POST", "DELETE"),
}
);
我的问题:是否真的需要自定义路由约束来完成此任务? 或者有什么方法可以使其与标准 MVC 和路由类一起开箱即用?
【问题讨论】:
标签: asp.net-mvc asp.net-mvc-3 url-routing asp.net-mvc-routing