ASP.NET MVC 2中的httppost、httpput等属性是如何工作的?

6
在ASP.NET MVC 2中,引入了一些新的操作过滤器属性,作为ASP.NET MVC 1中属性的“速记”;例如,应用HttpPostAttribute与将[AcceptVerbs(HttpVerbs.Post)]应用于动作方法相同。
此外,使用更冗长的语法,可以组合不同的方法,以允许例如PostDelete
现在我想知道:新属性是如何工作的?如果我同时应用[HttpPost][HttpDelete],ASP.NET MVC 2会允许两者还是需要两者(因此什么也不允许)?
4个回答

5
查看ActionMethodSelector的代码,似乎所有操作方法属性在IsValidForRequest返回true之前,都必须添加到可能匹配的方法集中。由于HttpPost和HttpDelete不可能为同一请求返回IsValidForRequest,因此使用两者都将防止该操作匹配任何请求。

以下是代码中的一个有意义的注释:

private static List RunSelectionFilters(...) {
//删除所有选择退出此请求的方法
//要选择退出,至少在方法上定义的一个属性必须返回false
}
(强调我的)

请注意,如果需要匹配任何一个动词,则仍然可以使用AcceptVerbs并显式OR这些动词。

编辑 - 这里有一个HttpPostOrDelete属性供您使用。
[AttributeUsage( AttributeTargets.Method, AllowMultiple = false, Inherited = false )]
public class HttpPostOrDeleteAttribute : ActionMethodSelectorAttribute
{
    private static readonly AcceptVerbsAttribute _innerPostAttribute = new AcceptVerbsAttribute( HttpVerbs.Post );
    private static readonly AcceptVerbsAttribute _innerDeleteAttribute = new AcceptVerbsAttribute( HttpVerbs.Delete );

    public override bool IsValidForRequest( ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo )
    {
        return _innerDeleteAttribute.IsValidForRequest( controllerContext, methodInfo )
               || _innerPostAttribute.IsValidForRequest( controllerContext, methodInfo );
    }
}

我知道我仍然可以使用“AcceptVerbs”,但我认为新的属性在代码中看起来更好,而且希望MVC团队在实现它们时考虑过这一点... - Tomas Aschan
@Tomas -- 幸运的是,你可以根据需要自己制作。请查看我的更新。 - tvanfosson

4

MVC中的所有过滤器 - 毫无例外 - 都是彼此独立的。在MVC框架中没有任何特殊情况下的过滤器。这是一个有意的设计决策,以便像调用程序这样的MVC框架组件不能“作弊”,并将位于MVC二进制文件中的过滤器与应用程序开发人员编写的过滤器区别对待。

因此,当调用程序看到同一方法上的[HttpGet]和[HttpPost]时,没有特殊的代码来取两者的并集。它们被独立执行。由于它们永远不可能为同一请求返回true,[HttpGet,HttpPost]有效地排除了任何特定方法成为操作方法。


3
您可以使用AcceptVerbs进行链接,例如:
[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
public ActionResult Customers() {
}

或者
[AcceptVerbs("GET","POST")]
public ActionResult Customers() {
}

0

如果你把[HttpPost][HttpDelete]放在一起,它会要求两者都存在(这是不可能的)。如果你链式使用[HttpGet],也不行,等等...

你可以很容易地测试它,只需取一个现有的[HttpPost]操作方法并添加[HttpDelete]。那么这个post就会停止工作。

我还没有找到任何需要像你建议的那样链接它们的例子。


我问这个问题的原因是我想允许POSTDELETE请求,但不允许其他请求。我本来希望属性会像联合集运算符一样工作,而不是交集运算符...但是,你并不总能得到你想要的。你有关于这种行为的来源吗? - Tomas Aschan
HttpPost和HttpDelete是非常常见的。如果您希望删除操作在使用AJAX(Delete)和非AJAX(Post)时都能正常运行,即使JavaScript被禁用,我会这样期望。 - tvanfosson
我实际上尝试了一次测试,但找不到任何组合可以使链式属性像你的例子一样工作。我采用了可行的方法,只是添加了属性,结果所有方法都崩溃了。 - Kelsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接