【问题标题】:Specify [HttpGet], [HttpPost] or [AcceptVerbs] for the whole controller为整个控制器指定 [HttpGet]、[HttpPost] 或 [AcceptVerbs]
【发布时间】:2014-06-05 17:16:35
【问题描述】:

可以在 ASP.NET MVC 中为整个 Controller 指定许多操作过滤器,从而将其应用于控制器中的所有操作。例如:

[Authorize]
public class MyController : Controller
{
    // ....
}

表示[Authorize]适用于控制器中的所有动作,非常方便。

但是当我尝试将[HttpGet][HttpPost][AcceptVerbs(...)] 放在控制器上时,编译器会抱怨该属性仅可用于方法(这是正确的,因为它们是用[AttributeUsage] 定义的,仅指向方法)。

如果我想将控制器中的所有操作限制为仅 POST 动词怎么办?

我的问题是:

  • 框架中是否有任何方法可以实现这一点,而无需编写我自己的属性?
  • 为什么这些属性以这种方式实现,却不允许在控制器上使用?

【问题讨论】:

  • 我认为在大多数情况下,控制器代表了一组相关的操作,这些操作是 GET 和 POST 的混合体,所以我明白为什么没有创建这个属性来应用于类级别。不过,这不会阻止你建立自己的。但是,如果您要发布某些内容,那么您不是从必须首先获取的内容发布吗?
  • @JasonNesbitt 是的,大多数时候。当我想为基于 Web 的 API 添加控制器时遇到了这种情况,我希望所有方法(操作)都用 [HttpPost] 标记,因为没有直接的用户交互,也没有来自同一个控制器的 GET 请求。

标签: c# asp.net asp.net-mvc asp.net-mvc-routing


【解决方案1】:

HttpGet 和 HttpPost 继承自 ActionMethodSelectorAttribute 类,仅对方法有效。我认为您需要创建自己的属性。

【讨论】:

    【解决方案2】:

    自定义属性来解决这个问题:

        public sealed class AllowedMethodsAttribute : ActionFilterAttribute
        {
            private readonly string[] methods;
    
            public AllowedMethodsAttribute(params string[] methods) => this.methods = methods.Select(r => r.Trim().ToUpperInvariant()).ToArray();
    
            public override void OnActionExecuting(ActionExecutingContext actionContext)
            {
                if (!methods.Contains(actionContext.HttpContext.Request.Method))
                {
                    actionContext.Result = new StatusCodeResult(405);
                }
            }
        }
    

    用法:

    [AllowedMethods("GET", "PATCH")]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      相关资源
      最近更新 更多