【问题标题】:.Net Web API - GetCookie() returns empty collection.Net Web API - GetCookie() 返回空集合
【发布时间】:2014-06-08 00:45:52
【问题描述】:

我尝试在后端 Web API 的 ApiController 中读取语言 cookie(我在客户端上设置),如下所示:

var cookieHeaderValue = Request.Headers.GetCookies("lang").FirstOrDefault();

我的请求标头如下所示:

也行

Request.Headers.GetCookies();

返回一个空集合... 谁能告诉我为什么以及我能做些什么来对付它? 请帮忙

【问题讨论】:

    标签: asp.net .net web-services asp.net-web-api


    【解决方案1】:

    CookieHeaderValue 的解析会因为 '?' 而失败在您的身份验证 cookie 名称中。尝试删除问号。

    【讨论】:

      【解决方案2】:

      这是一种“完全手动”且非常丑陋的 cookie 提取方法:

          /// <summary>
          /// Retrieves an individual cookie from the cookies collection
          /// </summary>
          /// <param name="request"></param>
          /// <param name="cookieName"></param>
          /// <returns></returns>
          public static string GetCookie(HttpRequestMessage request, string cookieName)
          {
              //var vHeaders = request.Headers;
              //foreach (var vHeader in vHeaders)
              //    System.Diagnostics.Debug.WriteLine(vHeader.Key + " - " + vHeader.Value);
      
              var vCookies = request.Headers.Where(H => H.Key.ToLower() == "cookie");
              if (vCookies != null)
              {
                  var vArrCookie = vCookies.FirstOrDefault().Value;
                  if (vArrCookie != null)
                  {
                      var vCookiePair = 
                          vArrCookie.FirstOrDefault().Split(new char[] { ';' }).Where(C => C.Trim().StartsWith(cookieName)).FirstOrDefault();
                      if (vCookiePair != null)
                      {
                          //System.Diagnostics.Debug.WriteLine(vCookiePair);
                          var vCookie = vCookiePair.Trim().Substring(cookieName.Length + 1);
                          return vCookie;
                      }
                  }
              }
      
              // DID NOT WORK
      
              //CookieHeaderValue cookie = request.Headers.GetCookies(cookieName).FirstOrDefault();
              //if (cookie != null)
              //    return cookie[cookieName].Value;
      
              return null;
          }
      

      将此方法添加到对 Web Api 控制器可见的基类或库类中。

      希望这会为您节省一些时间。

      干杯。

      【讨论】:

        【解决方案3】:

        这是从@Roman 修改的另一个版本,作为一种扩展方法,Linq 少一些,但不使用 StartsWith 更准确,如果 2 个或更多 cookie 以相同名称作为前缀,可能会导致误导性结果

        public static string GetCookieValue(this HttpRequestHeaders requestHeaders, string cookieName)
        {
            foreach (var header in requestHeaders)
            {
                if (header.Key.Equals("Cookie", StringComparison.InvariantCultureIgnoreCase) == false)
                    continue;
        
                var cookiesHeaderValue = header.Value.FirstOrDefault();
                if (cookiesHeaderValue == null)
                    return null;
        
                var cookieCollection = cookiesHeaderValue.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var cookieNameValue in cookieCollection)
                {
                    var parts = cookieNameValue.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length != 2) continue;
                    if (parts[0].Trim().Equals(cookieName, StringComparison.InvariantCultureIgnoreCase))
                        return parts[1].Trim();
                }
            }
        
            return null;
        }
        

        一些单元测试(nunit):

        [TestCase("hello=world;cookies=are fun;", "hello", "world", true)]
        [TestCase("HELlo=world;cookies=are fun", "hello", "world", true)]
        [TestCase("HELlo= world;cookies=are fun", "hello", "world", true)]
        [TestCase("HELlo =world;cookies=are fun", "hello", "world", true)]
        [TestCase("hello = world;cookies=are fun;", "hello", "world", true)]
        [TestCase("hellos=world;cookies=are fun", "hello", "world", false)]
        [TestCase("hello=world;cookies?=are fun?", "hello", "world", true)]
        [TestCase("hel?lo=world;cookies=are fun?", "hel?lo", "world", true)]
        public void Get_Cookie_Value_From_HttpRequestHeaders(string cookieHeaderVal, string cookieName, string cookieVal, bool matches)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
            var requestHeaders = request.Headers;
            requestHeaders.Add("Cookie", cookieHeaderVal);
        
            var valueFromHeader = requestHeaders.GetCookieValue(cookieName);
        
            if (matches)
            {
                Assert.IsNotNull(valueFromHeader);
                Assert.AreEqual(cookieVal, valueFromHeader);
            }
            else
            {
                Assert.IsNull(valueFromHeader);
            }                
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-25
          • 2021-07-06
          • 1970-01-01
          • 1970-01-01
          • 2019-02-13
          • 1970-01-01
          相关资源
          最近更新 更多