【问题标题】:Are there any constants for the default HTTP headers?默认 HTTP 标头是否有任何常量?
【发布时间】:2012-06-17 17:12:08
【问题描述】:

Microsoft 是否为标准 HTTP 标头名称创建了一个充满常量的类,还是我必须自己编写?

【问题讨论】:

    标签: c# asp.net http-headers


    【解决方案1】:

    请求标头

    /// <summary>
    /// Contains the standard set of headers applicable to an HTTP request.
    /// </summary>
    public static class HttpRequestHeaders
    {
        ///<summary>Content-Types that are acceptable</summary>
        public const string Accept = "Accept";
        ///<summary>Character sets that are acceptable</summary>
        public const string AcceptCharset = "Accept-Charset";
        ///<summary>Acceptable encodings. See HTTP compression.</summary>
        public const string AcceptEncoding = "Accept-Encoding";
        ///<summary>Acceptable languages for response</summary>
        public const string AcceptLanguage = "Accept-Language";
        ///<summary>Acceptable version in time</summary>
        public const string AcceptDatetime = "Accept-Datetime";
        ///<summary>Authentication credentials for HTTP authentication</summary>
        public const string Authorization = "Authorization";
        ///<summary>Used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain</summary>
        public const string CacheControl = "Cache-Control";
        ///<summary>What type of connection the user-agent would prefer</summary>
        public const string Connection = "Connection";
        ///<summary>an HTTP cookie previously sent by the server with Set-Cookie (below)</summary>
        public const string Cookie = "Cookie";
        ///<summary>The length of the request body in octets (8-bit bytes)</summary>
        public const string ContentLength = "Content-Length";
        ///<summary>A Base64-encoded binary MD5 sum of the content of the request body</summary>
        public const string ContentMD5 = "Content-MD5";
        ///<summary>The MIME type of the body of the request (used with POST and PUT requests)</summary>
        public const string ContentType = "Content-Type";
        ///<summary>The date and time that the message was sent</summary>
        public const string Date = "Date";
        ///<summary>Indicates that particular server behaviors are required by the client</summary>
        public const string Expect = "Expect";
        ///<summary>The email address of the user making the request</summary>
        public const string From = "From";
        ///<summary>The domain name of the server (for virtual hosting), mandatory since HTTP/1.1. Although domain name are specified as case-insensitive[5][6], it is not specified whether the contents of the Host field should be interpreted in a case-insensitive manner[7] and in practice some implementations of virtual hosting interpret the contents of the Host field in a case-sensitive manner.[citation needed]</summary>
        public const string Host = "Host";
        ///<summary>Only perform the action if the client supplied entity matches the same entity on the server. This is mainly for methods like PUT to only update a resource if it has not been modified since the user last updated it.</summary>
        public const string IfMatch = "If-Match";
        ///<summary>Allows a 304 Not Modified to be returned if content is unchanged</summary>
        public const string IfModifiedSince = "If-Modified-Since";
        ///<summary>Allows a 304 Not Modified to be returned if content is unchanged, see HTTP ETag</summary>
        public const string IfNoneMatch = "If-None-Match";
        ///<summary>If the entity is unchanged, send me the part(s) that I am missing; otherwise, send me the entire new entity</summary>
        public const string IfRange = "If-Range";
        ///<summary>Only send the response if the entity has not been modified since a specific time.</summary>
        public const string IfUnmodifiedSince = "If-Unmodified-Since";
        ///<summary>Limit the number of times the message can be forwarded through proxies or gateways.</summary>
        public const string MaxForwards = "Max-Forwards";
        ///<summary>Implementation-specific headers that may have various effects anywhere along the request-response chain.</summary>
        public const string Pragma = "Pragma";
        ///<summary>Authorization credentials for connecting to a proxy.</summary>
        public const string ProxyAuthorization = "Proxy-Authorization";
        ///<summary>Request only part of an entity. Bytes are numbered from 0.</summary>
        public const string Range = "Range";
        ///<summary>This is the address of the previous web page from which a link to the currently requested page was followed. (The word “referrer” is misspelled in the RFC as well as in most implementations.)</summary>
        public const string Referersic = "Referer[sic]";
        ///<summary>The transfer encodings the user agent is willing to accept: the same values as for the response header Transfer-Encoding can be used, plus the trailers value (related to the chunked transfer method) to notify the server it expects to receive additional headers (the trailers) after the last, zero-sized, chunk.</summary>
        public const string TE = "TE";
        ///<summary>Ask the server to upgrade to another protocol.</summary>
        public const string Upgrade = "Upgrade";
        ///<summary>The user agent string of the user agent</summary>
        public const string UserAgent = "User-Agent";
        ///<summary>Informs the server of proxies through which the request was sent.</summary>
        public const string Via = "Via";
        ///<summary>A general warning about possible problems with the entity body.</summary>
        public const string Warning = "Warning";
        ///<summary>Contains the original source address of the request.</summary>
        public const string XForwardedFor = "X-Forwarded-For";
    }
    

    响应标头

    /// <summary>
    /// Contains the standard set of headers applicable to an HTTP response.
    /// </summary>
    public static class HttpResponseHeaders
    {
        ///<summary>What partial content range types this server supports</summary>
        public const string AcceptRanges = "Accept-Ranges";
        ///<summary>The age the object has been in a proxy cache in seconds</summary>
        public const string Age = "Age";
        ///<summary>Valid actions for a specified resource. To be used for a 405 Method not allowed</summary>
        public const string Allow = "Allow";
        ///<summary>Tells all caching mechanisms from server to client whether they may cache this object. It is measured in seconds</summary>
        public const string CacheControl = "Cache-Control";
        ///<summary>Options that are desired for the connection[17]</summary>
        public const string Connection = "Connection";
        ///<summary>The type of encoding used on the data. See HTTP compression.</summary>
        public const string ContentEncoding = "Content-Encoding";
        ///<summary>The language the content is in</summary>
        public const string ContentLanguage = "Content-Language";
        ///<summary>The length of the response body in octets (8-bit bytes)</summary>
        public const string ContentLength = "Content-Length";
        ///<summary>An alternate location for the returned data</summary>
        public const string ContentLocation = "Content-Location";
        ///<summary>A Base64-encoded binary MD5 sum of the content of the response</summary>
        public const string ContentMD5 = "Content-MD5";
        ///<summary>An opportunity to raise a File Download dialogue box for a known MIME type with binary format or suggest a filename for dynamic content. Quotes are necessary with special characters.</summary>
        public const string ContentDisposition = "Content-Disposition";
        ///<summary>Where in a full body message this partial message belongs</summary>
        public const string ContentRange = "Content-Range";
        ///<summary>The MIME type of this content</summary>
        public const string ContentType = "Content-Type";
        ///<summary>The date and time that the message was sent</summary>
        public const string Date = "Date";
        ///<summary>An identifier for a specific version of a resource, often a message digest</summary>
        public const string ETag = "ETag";
        ///<summary>Gives the date/time after which the response is considered stale</summary>
        public const string Expires = "Expires";
        ///<summary>The last modified date for the requested object, inRFC 2822 format</summary>
        public const string LastModified = "Last-Modified";
        ///<summary>Used to express a typed relationship with another resource, where the relation type is defined by RFC 5988</summary>
        public const string Link = "Link";
        ///<summary>Used in redirection, or when a new resource has been created.</summary>
        public const string Location = "Location";
        ///<summary>This header is supposed to set P3P policy, in the form of P3P:CP=your_compact_policy. However, P3P did not take off,[22] most browsers have never fully implemented it, a lot of websites set this header with fake policy text, that was enough to fool browsers the existence of P3P policy and grant permissions for third party cookies.</summary>
        public const string P3P = "P3P";
        ///<summary>Implementation-specific headers that may have various effects anywhere along the request-response chain.</summary>
        public const string Pragma = "Pragma";
        ///<summary>Request authentication to access the proxy.</summary>
        public const string ProxyAuthenticate = "Proxy-Authenticate";
        ///<summary>Used in redirection, or when a new resource has been created. This refresh redirects after 5 seconds. This is a proprietary, non-standard header extension introduced by Netscape and supported by most web browsers.</summary>
        public const string Refresh = "Refresh";
        ///<summary>If an entity is temporarily unavailable, this instructs the client to try again after a specified period of time (seconds).</summary>
        public const string RetryAfter = "Retry-After";
        ///<summary>A name for the server</summary>
        public const string Server = "Server";
        ///<summary>an HTTP cookie</summary>
        public const string SetCookie = "Set-Cookie";
        ///<summary>A HSTS Policy informing the HTTP client how long to cache the HTTPS only policy and whether this applies to subdomains.</summary>
        public const string StrictTransportSecurity = "Strict-Transport-Security";
        ///<summary>The Trailer general field value indicates that the given set of header fields is present in the trailer of a message encoded with chunked transfer-coding.</summary>
        public const string Trailer = "Trailer";
        ///<summary>The form of encoding used to safely transfer the entity to the user. Currently defined methods are:chunked, compress, deflate, gzip, identity.</summary>
        public const string TransferEncoding = "Transfer-Encoding";
        ///<summary>Tells downstream proxies how to match future request headers to decide whether the cached response can be used rather than requesting a fresh one from the origin server.</summary>
        public const string Vary = "Vary";
        ///<summary>Informs the client of proxies through which the response was sent.</summary>
        public const string Via = "Via";
        ///<summary>A general warning about possible problems with the entity body.</summary>
        public const string Warning = "Warning";
        ///<summary>Indicates the authentication scheme that should be used to access the requested entity.</summary>
        public const string WWWAuthenticate = "WWW-Authenticate";       
    }
    

    【讨论】:

    • 我心想,“这些常量肯定存在于 .NET 框架中的某个地方”,但是当我反思 System.Net.Http.Headers.HttpRequestHeader.IfModifiedSince 时,我发现了嵌入的字符串“If-Modified-Since”不是一次,而是两次。
    • @Hugh 没那么快;即使它们是 const,编译器也会将这些字符串刻录到该代码中,请参阅stum.de/2009/01/14/… -此外,这就是为什么他们说永远不要将 const 用于可能会更改的字符串,因为它们会在引用中被烧毁并且最终可能会有所不同在不同时间编译的不同版本的库中。
    【解决方案2】:

    Microsoft 为请求和响应标头创建了枚举。

    看看以下内容:

    HttpResponseHeader

    HttpRequestHeader

    【讨论】:

    • 感谢 Jed - 有时框架就像在一家大型五金店的小岛上游荡,如您所见,我很不耐烦 ;)
    • 这不会为您提供字符串常量。虽然您可以执行HttpRequestHeader.AcceptLanguage.ToString(),但结果将是AcceptLanguage 而不是Accept-Language。所以我认为它并不能真正回答这个问题。
    • @Anton - OP 从未提到他正在寻找字符串常量 - 此外,他发布的评论(就在您的上方)暗示 MS 枚举就足够了。
    • @Jed - 确实。我想第一个答案让我相信这就是他想要的。对于那个很抱歉。只是建议进行修改并进行澄清,以便能够删除反对票。
    • 投反对票。此类指定枚举值而不是要求的字符串常量。
    【解决方案3】:

    扩展 Jed 的答案。

    HttpResponseHeaderHttpRequestHeader 枚举可以用作使用WebHeaderCollection 时的常量。 WebHeaderCollection 包含接受这些枚举的索引器属性。

    您可以使用字符串或枚举之一来获取和设置标头值,并在您的代码中混合使用。

    示例 LinqPad 脚本:

    var headers = new WebHeaderCollection();
    
    headers["If-Modified-Since"] = "Sat, 29 Oct 1994 19:43:31 GMT"; 
    // shows header name as "If-Modified-Since"
    headers.Dump();
    // shows expected header value of "Sat, 29 Oct 1994 19:43:31 GMT"
    headers[HttpRequestHeader.IfModifiedSince].Dump();
    
    headers.Clear();
    
    headers[HttpRequestHeader.IfModifiedSince] = "Sat, 29 Oct 1994 19:43:31 GMT";
    // shows header name as "If-Modified-Since"
    headers.Dump(); 
    // shows expected header value "Sat, 29 Oct 1994 19:43:31 GMT"
    headers["If-Modified-Since"].Dump();
    

    【讨论】:

    • 这些枚举似乎有整数值。是对它们调用.ToString() 的唯一选择,还是有另一种方法可以将名称作为字符串获取?
    • @crush 我不会使用ToString() 来获取值的字符串表示形式,因为许多标头值都有一个连字符,您不会以这种方式获得。
    • 谢谢,这是我没想到的好点。我正在尝试在 MVC 中的 Response 对象上设置标头。 System.Web.HttpResponseBase 版本 4.0.0.0。是否有一个包含我可以使用的字符串的枚举,或者我需要自己创建一个辅助类?
    • @crush 我不知道 .NET 中的某些内容会为您提供字符串常量。 Luke Puplett 的答案可能与您要找的很接近。
    【解决方案4】:

    他们在HttpKnownHeaderNames 中有它们,但不幸的是该类是内部的。我为它开了一个问题:https://github.com/dotnet/corefx/issues/10632

    【讨论】:

      【解决方案5】:

      我在尝试发现同一件事时发现了这个问题:标题名称常量作为字符串在哪里?

      在 ASP.NET Core 中,Microsoft.Net.Http.Headers.HeaderNames 是拯救我的类。

      public static class HeaderNames
        {
          public const string Accept = "Accept";
          public const string AcceptCharset = "Accept-Charset";
          public const string AcceptEncoding = "Accept-Encoding";
          public const string AcceptLanguage = "Accept-Language";
          public const string AcceptRanges = "Accept-Ranges";
          public const string Age = "Age";
          public const string Allow = "Allow";
          public const string Authorization = "Authorization";
          public const string CacheControl = "Cache-Control";
          public const string Connection = "Connection";
          public const string ContentDisposition = "Content-Disposition";
          public const string ContentEncoding = "Content-Encoding";
          public const string ContentLanguage = "Content-Language";
          public const string ContentLength = "Content-Length";
          public const string ContentLocation = "Content-Location";
          public const string ContentMD5 = "Content-MD5";
          public const string ContentRange = "Content-Range";
          public const string ContentType = "Content-Type";
          public const string Cookie = "Cookie";
          public const string Date = "Date";
          public const string ETag = "ETag";
          public const string Expires = "Expires";
          public const string Expect = "Expect";
          public const string From = "From";
          public const string Host = "Host";
          public const string IfMatch = "If-Match";
          public const string IfModifiedSince = "If-Modified-Since";
          public const string IfNoneMatch = "If-None-Match";
          public const string IfRange = "If-Range";
          public const string IfUnmodifiedSince = "If-Unmodified-Since";
          public const string LastModified = "Last-Modified";
          public const string Location = "Location";
          public const string MaxForwards = "Max-Forwards";
          public const string Pragma = "Pragma";
          public const string ProxyAuthenticate = "Proxy-Authenticate";
          public const string ProxyAuthorization = "Proxy-Authorization";
          public const string Range = "Range";
          public const string Referer = "Referer";
          public const string RetryAfter = "Retry-After";
          public const string Server = "Server";
          public const string SetCookie = "Set-Cookie";
          public const string TE = "TE";
          public const string Trailer = "Trailer";
          public const string TransferEncoding = "Transfer-Encoding";
          public const string Upgrade = "Upgrade";
          public const string UserAgent = "User-Agent";
          public const string Vary = "Vary";
          public const string Via = "Via";
          public const string Warning = "Warning";
          public const string WebSocketSubProtocols = "Sec-WebSocket-Protocol";
          public const string WWWAuthenticate = "WWW-Authenticate";
        }
      

      【讨论】:

      【解决方案6】:
      using System.Net.HttpRequestHeader;
      using System.Net.HttpResponseHeader;
      
      public class Example {
        static void Main() {
          Console.WriteLine(HttpRequestHeader.IfModifiedSince.ToHeaderString());
          // If-Modified-Since
      
          Console.WriteLine(HttpResponseHeader.ContentLength.ToHeaderString());
          // Content-Length
        }
      }
      
      static class ExtensionMethods {
        public static string ToHeaderString(this HttpRequestHeader instance)
        {
          return Regex.Replace(instance.ToString(), "(\\B[A-Z])", "-$1");
        }
      
        public static string ToHeaderString(this HttpResponseHeader instance)
        {
          return Regex.Replace(instance.ToString(), "(\\B[A-Z])", "-$1");
        }
      }
      

      【讨论】:

        【解决方案7】:

        Microsoft.Net.Http.Headers nuget 包中有一些可用的。在我的 asp.net 核心项目中它已经安装了。

        示例用法:

        var value = request.Headers[Microsoft.Net.Http.Headers.HeaderNames.IfNoneMatch]

        可能是某些人正在寻找的东西?

        【讨论】:

          【解决方案8】:

          如果您使用的是 .NET Framework(不是 .NET Core),您可以创建一个扩展方法来正确格式化 System.Net.HttpRequestHeader 枚举:

          using System;
          using System.Net;
          using System.Text;
          
          namespace YourNamespace
          {
             public static class HttpRequestHeaderEx
             {
                public static string ToStandardName(this HttpRequestHeader requestHeader)
                {
                   string headerName = requestHeader.ToString();
          
                   var headerStandardNameBuilder = new StringBuilder();
                   headerStandardNameBuilder.Append(headerName[0]);
          
                   for (int index = 1; index < headerName.Length; index++)
                   {
                      char character = headerName[index];
                      if (char.IsUpper(character))
                      {
                         headerStandardNameBuilder.Append('-');
                      }
          
                      headerStandardNameBuilder.Append(character);
                   }
          
                   string headerStandardName = headerStandardNameBuilder.ToString();
          
                   return headerStandardName;
                }
             }
          }
          

          用法:

             var userAgentHeaderName = HttpRequestHeader.UserAgent.ToStandardName();
          

          【讨论】:

            【解决方案9】:

            Microsoft.Net.Http.Headers.HeaderNames 类曾经是最好的,开箱即用的选项。

            但是从 ASP.NET Core 3.0 开始,该类具有静态只读字段而不是常量。原因是performance optimization of comparisons

            1. 引用比较比字符串内容顺序不区分大小写比较快。
            2. 常量成为消费程序集的一部分,而静态字段则不会。因此,在不同程序集中对常量的使用之间的引用过去是不同的,而在更改后,它们都是相同的。

            这种优化的缺点是“常量”不再是编译时常量,因此无法使用,例如带有属性 ([FromHeader(Name = HeaderNames.IfNoneMatch)])。

            只需在代码中创建您自己的类副本,使用实际常量而不是静态字段。

            【讨论】:

            • 据我所知,这在 ASP.NET Core 6 中仍然是准确的。
            猜你喜欢
            • 2012-05-08
            • 1970-01-01
            • 2017-01-30
            • 1970-01-01
            • 2021-02-04
            • 2011-03-26
            • 1970-01-01
            • 2021-03-18
            • 1970-01-01
            相关资源
            最近更新 更多