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 和注册路由的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net mvc和asp.net有啥区别?

Asp.net mvc和asp.net有啥区别?

ASP.NET MVC 和 Angularjs 与 ASP.NET MVC 和 Reactjs

浅析ASP.NET Webform和ASP.NET MVC

asp.net mvc 问题!

ASP.NET从MVC5升级到MVC6