.Net Web API - GetCookie()返回空集合

时间:2014-04-23 09:20:11

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

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

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

我的请求标头如下所示: enter image description here

也是

Request.Headers.GetCookies();

返回一个空集合...... 任何人都可以告诉我为什么以及我能做些什么呢? 请帮忙

3 个答案:

答案 0 :(得分:2)

由于'?',CookieHeaderValue的解析将失败在您的身份验证Cookie名称中。尝试删除问号。

答案 1 :(得分: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控制器可见的基类或库类中。

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

干杯。

答案 2 :(得分:1)

这是另一个从@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);
    }                
}