我很惊讶这还没有被提到,但是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;
}
}