我很惊讶这还没有被提及,但是 ASP.NET MVC 本身就支持 X-HTTP-Method-Override 并且至少从版本 2 开始就已经这样做了。不需要编写自定义代码来处理这个问题。
它以下列方式工作:
在 AcceptVerbsAttribute(也由 [HttpPut]、[HttpPost] 等代理)内部,有一个 IsValidForRequest 方法。在该方法中,它使用 Request.GetHttpMethodOverride() 进行检查,该方法返回具有以下条件的正确覆盖的 HTTP 方法:
- 仅在 POST 请求中支持覆盖。所有其他都被忽略。
- 如果 X-HTTP-Method-Override 值为 GET 或 POST,则会被忽略。这是有道理的,因为您永远不需要覆盖这些值。
- 它在此优先级的以下位置查找 X-HTTP-Method-Override:1)HTTP 标头 2)表单正文 3)查询字符串
如果你真的很好奇,下面是 GetHttpMethodOverride() 的样子(来自 MVC 3 的源代码):
public static class HttpRequestExtensions {
internal const string XHttpMethodOverrideKey = "X-HTTP-Method-Override";
public static string GetHttpMethodOverride(this HttpRequestBase request) {
if (request == null) {
throw new ArgumentNullException("request");
}
string incomingVerb = request.HttpMethod;
if (!String.Equals(incomingVerb, "POST", StringComparison.OrdinalIgnoreCase)) {
return incomingVerb;
}
string verbOverride = null;
string headerOverrideValue = request.Headers[XHttpMethodOverrideKey];
if (!String.IsNullOrEmpty(headerOverrideValue)) {
verbOverride = headerOverrideValue;
}
else {
string formOverrideValue = request.Form[XHttpMethodOverrideKey];
if (!String.IsNullOrEmpty(formOverrideValue)) {
verbOverride = formOverrideValue;
}
else {
string queryStringOverrideValue = request.QueryString[XHttpMethodOverrideKey];
if (!String.IsNullOrEmpty(queryStringOverrideValue)) {
verbOverride = queryStringOverrideValue;
}
}
}
if (verbOverride != null) {
if (!String.Equals(verbOverride, "GET", StringComparison.OrdinalIgnoreCase) &&
!String.Equals(verbOverride, "POST", StringComparison.OrdinalIgnoreCase)) {
incomingVerb = verbOverride;
}
}
return incomingVerb;
}
}