ASP.NET MVC AcceptVerbs 和注册路由
Posted
技术标签:
【中文标题】ASP.NET MVC AcceptVerbs 和注册路由【英文标题】:ASP.NET MVC AcceptVerbs and registering routes 【发布时间】:2010-09-21 22:39:34 【问题描述】:如果我已经用 [AcceptVerbs(..)] 属性修饰了我的操作方法,我是否必须在我的路由定义中注册 HttpVerb 约束(当我注册路由时)?
例如。我有这个。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection formCollection)
..
我是否需要将此作为约束添加到引用此操作的路由中?
【问题讨论】:
【参考方案1】:两者之间的区别如下:假设有问题的Create
方法在HomeController
上。
使用AcceptVerbs
属性不会影响路由。它实际上是动作调用者使用的东西。它允许您在一个控制器上拥有 2 个具有相同名称的操作方法,每个方法响应不同的 HTTP 方法。
public ActionResult Create(int id) ..
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection formCollection) ..
所以当/home/create
的请求进来时,路由会匹配并将请求交给控制器的调用者。然后调用者通过查看AcceptVerbs
属性调用正确的方法。
在路由中使用HttpMethodConstraint
会使路由本身与请求不匹配。因此,当 /home/create
收到 POST 请求时,不会调用任何操作方法,因为该路由与请求不匹配。不过,有可能另一条路线将匹配该请求。
此处出现重叠的部分原因是路由是 ASP.NET 3.5 SP1 的一项功能,并非特定于 MVC。 MVC 使用路由,但动态数据也使用路由,我们计划将路由与 ASP.NET Web 窗体集成。
【讨论】:
@Phil:我了解控制器的调用者如何根据 AcceptVerbs 选择最佳方法的第一部分。第二部分没看懂你是说如果你使用 HttpMethodConstraint,它就不会知道使用哪个 Create 方法? 不,我是说使用约束意味着路由本身不匹配。如果没有匹配的路由,则首先不会将请求传递给 MVC。 @Haacked - 这篇文章已经很久了,但我对这两种技术都有疑问。我正在使用 MVC3 并尝试以 RESTful 方式为我的应用程序构建 JSON api。这意味着我有一个需要处理 3 个动词(POST、PUT、DELETE)的路由 - 在路由级别使用约束并在路由中连接 3 个单独的操作会更聪明......或者更好地构建MVC 框架中的一个属性,它捕获多个动词并将它们作为参数传递给动作? @Haacked - 纠正自己并更具体地说,GET、PUT、DELETE 都共享相同的路由签名/objName/id
,我试图让一个控制器动作处理接受所有三个动词 - or- 3 个动作(每个动词一个)但名称和方法签名相同(仅使用属性不可能)
如果您想要完全相同的方法来处理它们,请在其上使用 3 个属性:[HttpPost][HttpGet][HttpDelete]public ActionResult MyMethod()【参考方案2】:
不 -- Create 只会响应 POST 请求。
您可以使用其他具有不同 AcceptVerb 属性的 Create 实现,或者一个没有捕获所有其他请求的属性的实现。
如果这是您唯一的 Create 方法,那么任何 GET(或其他非 POST)请求都会导致 404。
我假设这一切都是由路由引擎完成的。 [编辑:不,见 Haacked 的帖子]
【讨论】:
是的 - 我明白这一切,但这不是问题所在。路由定义中定义的 AcceptVerb 属性与 HttpVerb 约束有什么区别?什么都没有......只是让你的船以任何方式漂浮?【参考方案3】:首先这样装饰:
[ActionName("ItemEdit"), AcceptVerbs(HttpVerbs.Post)]
public virtual object ItemSave(Menu sampleInput)
那么你需要像这样添加路由:
AddRoute(
"SampleEdit",
"Admin/sampleID/Edit",
new controller = "Sample", action = "ItemEdit", validateAntiForgeryToken = true ,
new areaID = new IsGuid() ,
new Namespaces = controllerNamespaces
);
【讨论】:
以上是关于ASP.NET MVC AcceptVerbs 和注册路由的主要内容,如果未能解决你的问题,请参考以下文章