ASP.NET MVC - HttpPostAttribute, HttpGetAttribute, AcceptVerbsAttribute 等

创建时间:
2018-09-05 12:36
最近更新:
2018-09-05 12:36

TonyNote: [HttpPost] 命名为 [HttpPostOnly] 更贴切

System.Web.Mvc 命名空间 下的相关 属性 (Attribute)

  1. HttpDeleteAttribute
  2. HttpGetAttribute
  3. HttpHeadAttribute
  4. HttpOptionsAttribute
  5. HttpPatchAttribute
  6. HttpPostAttribute
  7. HttpPutAttribute
  • 以上 7 个属性 在 MSDN 的描述相似: Represents an attribute that is used to restrict an action method so that the method handles only HTTP DELETE/GET/HEAD/OPTIONS/PATCH/POST/PUT requests (译文: 表示 一个属性,该属性 被用于 限制 一个操作方法,以便 该方法 只处理 HTTP DELETE/GET/HEAD/OPTIONS/PATCH/POST/PUT 请求).
  • 以上 7 个属性 与 System.Web.Mvc.HttpVerbs 枚举 中的项 一致。

Source Code of System.Web.Mvc.HttpGetAttribute from JetBrains dotPeek 1.0 at 2018-09-05

对比记录: 把下方的 System.Web.Mvc.HttpPostAttribute 源码中的 全部 post (共 5 个) 替换成 get 就是 System.Web.Mvc.HttpGetAttribute 的源码。

Source Code of System.Web.Mvc.HttpPostAttribute from JetBrains dotPeek 1.0 at 2018-09-05

Complete Copy:

// Type: System.Web.Mvc.HttpPostAttribute
// Assembly: System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_4.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll

using System;
using System.Reflection;

namespace System.Web.Mvc
{
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public sealed class HttpPostAttribute : ActionMethodSelectorAttribute
  {
    private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);

    static HttpPostAttribute()
    {
    }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
      return HttpPostAttribute._innerAttribute.IsValidForRequest(controllerContext, methodInfo);
    }
  }
}

Source Code of System.Web.Mvc.ActionMethodSelectorAttribute from JetBrains dotPeek 1.0 at 2018-09-05

Complete Copy:

// Type: System.Web.Mvc.ActionMethodSelectorAttribute
// Assembly: System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_4.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll

using System;
using System.Reflection;

namespace System.Web.Mvc
{
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public abstract class ActionMethodSelectorAttribute : Attribute
  {
    public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);
  }
}

Source Code of System.Web.Mvc.AcceptVerbsAttribute from JetBrains dotPeek 1.0 at 2018-09-05

Complete Copy:

// Type: System.Web.Mvc.AcceptVerbsAttribute
// Assembly: System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_4.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Web.Mvc.Properties;

namespace System.Web.Mvc
{
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute
  {
    public ICollection<string> Verbs { get; private set; }

    public AcceptVerbsAttribute(HttpVerbs verbs)
      : this(AcceptVerbsAttribute.EnumToArray(verbs))
    {
    }

    public AcceptVerbsAttribute(params string[] verbs)
    {
      if (verbs == null || verbs.Length == 0)
        throw new ArgumentException(MvcResources.Common_NullOrEmpty, "verbs");
      this.Verbs = (ICollection<string>) new ReadOnlyCollection<string>((IList<string>) verbs);
    }

    private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string entryText)
    {
      if ((verbs & match) == (HttpVerbs) 0)
        return;
      verbList.Add(entryText);
    }

    internal static string[] EnumToArray(HttpVerbs verbs)
    {
      List<string> verbList = new List<string>();
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Patch, verbList, "PATCH");
      AcceptVerbsAttribute.AddEntryToList(verbs, HttpVerbs.Options, verbList, "OPTIONS");
      return verbList.ToArray();
    }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
      if (controllerContext == null)
        throw new ArgumentNullException("controllerContext");
      else
        return Enumerable.Contains<string>((IEnumerable<string>) this.Verbs, HttpRequestExtensions.GetHttpMethodOverride(controllerContext.HttpContext.Request), (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
    }
  }
}