是否可以在 ASP.NET MVC 中实现 X-HTTP-Method-Override?
我正在使用 ASP.NET MVC 实现 RESTful API 的原型,除了这里那里的奇怪错误之外,我已经实现了我在开始时提出的所有要求,除了调用者能够使用 X -HTTP-Method-Override
自定义标头以覆盖 HTTP 方法。
我想要的是以下请求...
GET /someresource/123 HTTP/1.1
X-HTTP-Method-Override: DELETE
...将被分派到我的控制器方法,该方法实现该操作的 DELETE
功能而不是 GET
功能(假设有多个方法实现该操作,并且它们标记有不同的 [AcceptVerbs]
属性)。 因此,鉴于以下两种方法,我希望将上述请求分派给第二种方法:
[ActionName("someresource")]
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetSomeResource(int id) { /* ... */ }
[ActionName("someresource")]
[AcceptVerbs(HttpVerbs.Delete)]
public ActionResult DeleteSomeResource(int id) { /* ... */ }
有人知道这是否可能吗? 这样做需要做多少工作......?
I'm implementing a prototype of a RESTful API using ASP.NET MVC and apart from the odd bug here and there I've achieve all the requirements I set out at the start, apart from callers being able to use the X-HTTP-Method-Override
custom header to override the HTTP method.
What I'd like is that the following request...
GET /someresource/123 HTTP/1.1
X-HTTP-Method-Override: DELETE
...would be dispatched to my controller method that implements the DELETE
functionality rather than the GET
functionality for that action (assuming that there are multiple methods implementing the action, and that they are marked with different [AcceptVerbs]
attributes). So, given the following two methods, I would like the above request to be dispatched to the second one:
[ActionName("someresource")]
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetSomeResource(int id) { /* ... */ }
[ActionName("someresource")]
[AcceptVerbs(HttpVerbs.Delete)]
public ActionResult DeleteSomeResource(int id) { /* ... */ }
Does anybody know if this is possible? And how much work would it be to do so...?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
X-HTTP-Method-Override
是自定义标头,您的 Web 容器很可能不支持。您是从网页调用这个吗? 如果是这样,您可能应该将
XmlHttpRequest
与DELETE
(或您想要的任何动词)一起使用。 更好的是,使用 JS 框架来为您完成繁重的工作。The
X-HTTP-Method-Override
is a custom header and most likely isn't supported by your web container.Are you calling this from a web page? If so, you should probably use
XmlHttpRequest
withDELETE
(or whatever verb you want). Better yet, use a JS framework to do the heavy lifting for you.您可以创建一个实现 OnActionExecuting 的 ActionFilter,该过滤器在调用控制器操作之前触发。 然后,您可以询问请求标头,并根据 X-HTTP-Method-Override 标头(如果存在)的值进行重定向。
You could create an ActionFilter that implements
OnActionExecuting
, which fires before the controller action is invoked. You could then interrogate the request headers, and redirect based on the value of theX-HTTP-Method-Override
header, when present.您将无法按原样使用 [AcceptVerbs] 属性,因为它与请求的实际 HTTP 动词相关联。 幸运的是,[AcceptVerbs] 属性非常简单; 您可以在 http://www.codeplex.com/aspnet/SourceControl/changeset/view/21528#266431< /a>.
简而言之,子类 AcceptsVerbsAttribute 并重写 IsValidForRequest() 方法。 实现将类似于以下内容:
You won't be able to use the [AcceptVerbs] attribute as-is since it's tied to the request's actual HTTP verb. Fortunately the [AcceptVerbs] attribute is very simple; you can see the source for yourself at http://www.codeplex.com/aspnet/SourceControl/changeset/view/21528#266431.
In short, subclass AcceptsVerbsAttribute and override the IsValidForRequest() method. The implementation would be something like the following:
莱维的回答很棒。 此外,我在自定义 AcceptsVerbsAttribute 中添加了一个检查,它还检查 FORM 集合,因此您只需放置一个隐藏输入即可触发 DELETE(类似于 MVC 2 的
Html.HttpMethodOverride(HttpVerbs.Delete)
) 。将传入动词分配更改为:
小心这种方法! 请参阅 相关帖子。
希望这对某人有帮助。
Levi's answer is great. Additionally, I added a check in the custom AcceptsVerbsAttribute that also examines the FORM collection, so you can simply put a hidden input to trigger the DELETE (similar to MVC 2's
Html.HttpMethodOverride(HttpVerbs.Delete)
).Change the incomingVerb assignment to:
Be careful with this approach! See a related post by Stephen Walther.
Hopefully this helps someone.
插入表格:
Insert to Form:
这个对话有点老了,但我想分享我使用 mvc 2 发现的内容:
浏览器支持两种 HTTP 动词:GET 和 POST,但 ASP.NET MVC 2 允许您使用 Html.HttpMethodOverride 模拟 Put、Get 和 Delete辅助方法。 在内部,这是通过在 X-HTTP-Method-Override 表单字段中发送动词来实现的。 HttpMethodOverride 的行为由 [AcceptVerbs] 属性以及新的较短动词属性使用:
例如,操作声明:
应该对 X-HTTP-Method-Override 设置为“Delete”的 get 请求负责。
This conversation is a bit old, but I wanted to share what I have found using mvc 2:
Browsers support two HTTP verbs: GET and POST, but ASP.NET MVC 2 allows you to simulate Put, Get, and Delete using Html.HttpMethodOverride helper method. Internally, this works by sending the verb in an X-HTTP-Method-Override form field. The behavior of HttpMethodOverride is used by the [AcceptVerbs] attribute as well as the new shorter verb attributes:
For example, the action declaration:
should take responsibility for your get request that has the X-HTTP-Method-Override set to Delete.
令我惊讶的是,这一点尚未被提及,但 ASP.NET MVC 本身支持 X-HTTP-Method-Override,并且至少从版本 2 开始就这样做了。无需编写自定义代码来处理此问题。
它的工作方式如下:
在 AcceptVerbsAttribute 内部(也由 [HttpPut]、[HttpPost] 等代理),有一个 IsValidForRequest 方法。 在该方法内部,它会检查 Request.GetHttpMethodOverride(),后者会返回具有以下条件的正确重写 HTTP 方法:
1) HTTP 标头
2) 表格主体
3) 查询字符串
如果您真的很好奇,那么 GetHttpMethodOverride() 的外观如下(来自 MVC 3 的源代码):
I'm surprised that this hasn't been mentioned yet, but ASP.NET MVC natively supports X-HTTP-Method-Override and has been doing so from at least version 2. There's no need to write custom code to handle this.
It work in the following way:
Inside AcceptVerbsAttribute (also proxied by [HttpPut], [HttpPost], etc), there's an IsValidForRequest method. Inside that method, it checks with Request.GetHttpMethodOverride(), which returns the proper overriden HTTP method with the following conditions:
1) HTTP Header
2) Form Body
3) Query String
If you're really curious, here's how GetHttpMethodOverride() looks (from MVC 3's source code):
您是否看过简单的静态路由? 它已经这样做了。
2010 年 2 月编辑添加:方法重写内置于 MVC 2 中。
Have you looked at Simply Restful Routing? It already does this.
Edited Feb 2010 to add: Method overrides are built into MVC 2.