我有一个自托管的WCF服务,其端点设置使用WebHttpBinding监听HTTP请求.我需要访问通过这些请求传递的cookie.我可以得到Cookie:标头值,但我坚持实际解析.我的实现尝试使用CookieContainer:
var container = new CookieContainer();
var uri = new Uri("http://localhost/");
container.SetCookies(uri, cookieHeader);
var cookies = container.GetCookies(uri).OfType<Cookie>();
foreach (var cookie in cookies)
{
    Console.WriteLine("{0} = {1}", cookie.Name, cookie.Value);
}
这段代码的问题是,CookieContainer期望cookie用逗号(cookieHeader="c1=v1,c2=v2")分隔,而浏览器倾向于使用分号(cookieHeader="c1=v1;c2=v2").由于RFC 6265只允许使用分号作为分隔符(虽然旧的RFC允许),我有点困惑为什么CookieContainer只支持逗号.现在我正在努力寻找一个似乎非常典型的问题的替代解决方案.如何正确解析cookie?ASP.NET应该能够做到这一点,它是否公开了任何可公开使用的类?
Mit*_*tch 12
据我了解,分隔符因a Set-Cookie:和Cookie:标题而异.  Set-Cookie:如果存在多个标头,则通常会重复,而Cookie:在单个标头中有多个Cookie.来自RFC6265:
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
该Set-Cookie:首标可以组合通过附加由逗号分隔的每个报头为单个串:
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly,lang=en-US; Path=/; Domain=example.com
CookieContainer设计用于客户端(由用户代理),因此该SetCookies(Uri, string)方法仅解析使用的语法Set-Cookie:.
ASP.Net使用内部方法来解析Cookie:标头,并且它似乎没有被任何公共方法公开.见HttpListenerRequest.Cookies:
private CookieCollection ParseCookies(Uri uri, string setCookieHeader) {
    GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ParseCookies() uri:" + uri + " setCookieHeader:" + setCookieHeader);
    CookieCollection cookies = new CookieCollection();
    CookieParser parser = new CookieParser(setCookieHeader);
    for (;;) {
        Cookie cookie = parser.GetServer();
        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ParseCookies() CookieParser returned cookie:" + ValidationHelper.ToString(cookie));
        if (cookie==null) {
            // EOF, done.
            break;
        }
        if (cookie.Name.Length==0) {
            continue;
        }
        cookies.InternalAdd(cookie, true);
    }
    return cookies;
}
Nancy有一个非常简洁的解析器,如果许可允许,可以使用它:
private IDictionary<string, string> GetCookieData()
{
    var cookieDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    if (!this.Headers.Cookie.Any())
    {
        return cookieDictionary;
    }
    var values = this.Headers["cookie"].First().TrimEnd(';').Split(';');
    foreach (var parts in values.Select(c => c.Split(new[] { '=' }, 2)))
    {
        var cookieName = parts[0].Trim();
        string cookieValue;
        if (parts.Length == 1)
        {
            //Cookie attribute
            cookieValue = string.Empty;
        }
        else
        {
            cookieValue = parts[1];
        }
        cookieDictionary[cookieName] = cookieValue;
    }
    return cookieDictionary;
}
| 归档时间: | 
 | 
| 查看次数: | 4833 次 | 
| 最近记录: |