【问题标题】:How do the httppost, httpput etc attributes in ASP.NET MVC 2 work?ASP.NET MVC 2 中的 httppost、httpput 等属性如何工作?
【发布时间】:2010-04-15 20:34:18
【问题描述】:

在 ASP.NET MVC 2 中,引入了几个新的操作过滤器属性,作为 ASP.NET MVC 1 中属性的“简写”;例如,应用HttpPostAttribute 与将[AcceptVerbs(HttpVerbs.Post)] 应用到操作方法的作用相同。

此外,使用更详细的语法,可以组合不同的方法,以便同时允许PostDelete

现在我想知道:新属性是如何工作的?如果我同时应用[HttpPost][HttpDelete],ASP.NET MVC 2 会 allow 两者还是 require 两者(因此什么都不允许)?

【问题讨论】:

    标签: c# asp.net-mvc-2 action-filter http-method


    【解决方案1】:

    查看 ActionMethodSelector 的代码,似乎所有操作方法属性都必须为 IsValidForRequest 返回 true,然后才能将该操作添加到可能的匹配方法集中。由于 HttpPost 和 HttpDelete 不可能为同一个请求返回 IsValidForRequest,因此我希望同时使用两者会阻止该操作匹配任何请求。

    以下是代码中的一条有说服力的注释:

    私有静态列表 RunSelectionFilters(...) {
    // 删除所有选择退出此请求的方法
    // 要退出,方法上定义的至少一个属性必须返回 false

    (强调我的)

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

    EDIT -- 这里有一个 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 -- 幸运的是,您可以根据需要自己制作。查看我的更新。
    【解决方案2】:

    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() {
      }
      

      【讨论】:

        【解决方案4】:

        如果你把[HttpPost][HttpDelete] 放在一起,我想这两者都需要(这是不可能的)。如果你链接[HttpGet] 它也不会工作,等等......

        您只需采用现有的[HttpPost] 操作方法并向其添加[HttpDelete] 即可轻松对其进行测试。该帖子将停止工作。

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

        【讨论】:

        • 我问的原因是我想允许 both POST 和 DELETE 请求,但不允许其他请求。我曾希望属性能够像 UNION 集合运算符而不是 INTERSECTION 运算符一样工作......但是,你不能总是得到你想要的。你在某处有这种行为的来源吗?
        • 我实际上尝试了一个测试,但找不到任何可以让像您的示例一样的链接属性起作用的组合。我采用了工作方法,只是为它们添加了属性,果然它破坏了它们。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多