C# 为整个控制器指定[HttpGet]、[HttpPost]或[AcceptVerbs]

C# 为整个控制器指定[HttpGet]、[HttpPost]或[AcceptVerbs],c#,asp.net,asp.net-mvc,asp.net-mvc-routing,C#,Asp.net,Asp.net Mvc,Asp.net Mvc Routing,在ASP.NET MVC中,可以为整个控制器指定许多操作筛选器,从而将其应用于控制器中的所有操作。例如: [Authorize] public class MyController : Controller { // .... } 表示[Authorize]应用于控制器中的所有操作,这非常方便 但是,当我试图将[HttpGet]、[HttpPost]或[AcceptVerbs(…)]放在控制器上时,编译器会抱怨该属性仅可用于方法(这是正确的,因为它们是用只指向方法的[Attribute

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

[Authorize]
public class MyController : Controller
{
    // ....
}
表示
[Authorize]
应用于控制器中的所有操作,这非常方便

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

如果我想将控制器中的所有操作都限制为仅POST谓词,该怎么办

我的问题是:

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

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

自定义属性可以解决此问题:

    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")]

我认为在大多数情况下,控制器表示一组相关的操作,它们是GET和POST的混合体,因此我可以理解为什么创建此属性不是为了应用于类级别。但这不会阻止你建立自己的公司。如果你在发布一些东西,你不是在发布一些你必须首先得到的东西吗?@JasonNesbitt是的,大多数时候是这样。我在为基于web的API添加控制器时遇到了这种情况,我希望所有方法(操作)都标记为[HttpPost],因为没有直接的用户交互,也没有来自同一控制器的GET请求。