C# 关于.NET CookieContainer的帮助

C# 关于.NET CookieContainer的帮助,c#,cookies,C#,Cookies,我最近在CookieContainer上遇到了一些问题。要么是我做错了什么,要么是CookieContainer对象出现了某种bug。它似乎没有使用某些设置的cookie头更新cookie集合 这可能是一篇冗长的文章,我对此表示歉意,但我希望尽可能详细,因此我将列出我的HTTP嗅探日志以及实际的实现代码 public bool SendRequest(HttpWebRequest request, IDictionary<string, string> data, int r

我最近在CookieContainer上遇到了一些问题。要么是我做错了什么,要么是CookieContainer对象出现了某种bug。它似乎没有使用某些设置的cookie头更新cookie集合

这可能是一篇冗长的文章,我对此表示歉意,但我希望尽可能详细,因此我将列出我的HTTP嗅探日志以及实际的实现代码

    public bool SendRequest(HttpWebRequest request, IDictionary<string, string> data, int retries)
    {
        // copy request in case request instance already failed
        HttpWebRequest newRequest = (HttpWebRequest)HttpWebRequest.Create(request.RequestUri);
        newRequest.Method = request.Method;

        // if POST data was provided, write it to the stream
        if (data != null && data.Count != 0)
        {
            StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
            writer.Write(createPostString(data));
            writer.Close();
        }

        // set request with global cookie container
        newRequest.CookieContainer = this.cookieJar;

        try
        {
            using (HttpWebResponse resp = (HttpWebResponse)newRequest.GetResponse())
            {
                //CookieCollection newCooks = getCookies(resp.Headers);
                //updateCookies(newCooks);
                this.cookieJar = newRequest.CookieContainer;
                this.Html = getResponseString(resp);

             /* remainder snipped */
响应1

POST /login/ HTTP/1.1
Host: www.site.com
Content-Length: 47
Expect: 100-continue
Connection: Keep-Alive
HTTP/1.1 200 OK
Date: Wed, 02 Dec 2009 17:03:35 GMT
Server: Apache
Set-Cookie: tcc=one; path=/
Set-Cookie: cust_id=2702585226; domain=.site.com; path=/; expires=Mon, 01-Jan-2011 00:00:00 GMT
Set-Cookie: cust_session=12%2F2%2F2009%20%2012%3A3%3A35; domain=.site.com; path=/; expires=Wed 2-Dec-2009  17:33:35
Set-Cookie: refer_id_persistent=0000; domain=.site.com; path=/; expires=Fri 2-Dec-2011  17:3:35
Set-Cookie: refer_id=0000; domain=.site.com; path=/
Set-Cookie: private_browsing_mode=off; domain=.site.com; path=/; expires=Fri, 01-Jan-2010 17:03:35 GMT
Set-Cookie: member_session=UmFuZG9tSVYL%5BS%5D%5BP%5DfhH77bYaVoS9j9Yd8ySRkyHHz%5BS%5Dk0S8MVsQ6AyraNlcdcCRC0RkB%5BP%5DfBYVM4vn6JQ3HlJxT3GlJi1RZiMGQaITg7HN9dpu9oRbZgMjhJlXXa%5BP%5D7pFSjqDIZWRr3LAfnhh3btv4E3rvVH42CeOP%5BS%5Dx6kDyvrokQEHyIHPGi7zswZbuHrUdx2XKEKKJzw1unDWfw0LZWjoehAs0QgSOz6Nzp8P4Hp8hqrULdIMch6acPT%5BS%5DbKV8zwugBIcjr5dI3rVR%5BP%5Dv42rsTtQB7dyb%5BP%5DRKb8Y83cGqhHM33hP%5BP%5DUtmbDC1PPfr%5BS%5DPC23lAO%5BS%5DmQ3mOy9x4pgQSOfp40XSfzgVg3EavITaxHBeI5nO3%5BP%5D%5BS%5D2rSDthDfuEm4sT9i6UF3sYd1vlOL0IC9ZsVatV1yhhpQ%5BE%5D%5BE%5D; domain=.site.com; path=/; expires=Fri, 01-Jan-2010 17:03:35 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
请求2

GET /test?search=jjkjf HTTP/1.1
Host: www.site.com
Cookie: tcc=one; cust_id=2702585226; private_browsing_mode=off; member_session=UmFuZG9tSVYL%5BS%5D%5BP%5DfhH77bYaVoS9j9Yd8ySRkyHHz%5BS%5Dk0S8MVsQ6AyraNlcdcCRC0RkB%5BP%5DfBYVM4vn6JQ3HlJxT3GlJi1RZiMGQaITg7HN9dpu9oRbZgMjhJlXXa%5BP%5D7pFSjqDIZWRr3LAfnhh3btv4E3rvVH42CeOP%5BS%5Dx6kDyvrokQEHyIHPGi7zswZbuHrUdx2XKEKKJzw1unDWfw0LZWjoehAs0QgSOz6Nzp8P4Hp8hqrULdIMch6acPT%5BS%5DbKV8zwugBIcjr5dI3rVR%5BP%5Dv42rsTtQB7dyb%5BP%5DRKb8Y83cGqhHM33hP%5BP%5DUtmbDC1PPfr%5BS%5DPC23lAO%5BS%5DmQ3mOy9x4pgQSOfp40XSfzgVg3EavITaxHBeI5nO3%5BP%5D%5BS%5D2rSDthDfuEm4sT9i6UF3sYd1vlOL0IC9ZsVatV1yhhpQ%5BE%5D%5BE%5D


如您所见,用于每个请求的CookieContainer(this.cookieJar)没有为refere\u id、cust\u session、refere\u id\u persistent拾取设置的Cookie头。不过,它会获取客户id、私人浏览模式、tcc和会员会话。。。知道为什么会这样吗?

这只是对代码的快速扫描,但似乎在发送请求中的Cookie之前发送了post数据

   if (data != null && data.Count != 0)
    {
        StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
        writer.Write(createPostString(data));
        writer.Close();
    }

    // set request with global cookie container
    newRequest.CookieContainer = this.cookieJar;
可能发生的情况是,当您将post数据写入流时,它将被发送到远程服务器。但是,要设置cookie,必须在任何postdata之前将其发送到服务器。简单的解决方案是这样交换:

 // set request with global cookie container
 newRequest.CookieContainer = this.cookieJar;

 if (data != null && data.Count != 0)
    {
        StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
        writer.Write(createPostString(data));
        writer.Close();
    }

我只是想更新一下这篇文章,以防有人发现。问题是.NET符合cookie标记的RFC规范,但并非所有站点都符合。因此,归根结底,问题不在于微软,也不在于.NET。(虽然,也就是说,cookie管理得很好,因此最好使用相同的解析方法重写它们的.NET cookie解析方法)问题在于没有遵循这些方法的站点

尽管如此,我经常遇到的一个问题是,网站会在cookie的过期日期中使用逗号。NET将这些字段解释为不同cookie字段之间的分隔符,并从cookie中去掉结尾和后面的所有内容


:“Cookie:,后面是一个逗号分隔的一个或多个Cookie列表。”解决此问题的一个简单方法是web服务器根据RFC文档用引号将值括起来。但是,没有RFC警察,因此我们只能希望人们遵守规则。

尝试使用CookieContainer.GetCookieHeader和CookieContainer.SetCookies

YourCookieContainer.GetCookieHeader(new Uri("your url"));

YourCookieContainer.SetCookies(new Uri("your url"), "string from GetCookieHeader");
MSDN SetCookies: SetCookies从HTTP cookie头中取出所有HTTP cookie,为每个cookie构建一个cookie,然后将每个cookie添加到与URI关联的内部CookieCollection。cookieHeader字符串中的HTTP cookie必须用逗号分隔

MSDN GetCookieHeader GetCookieHeader返回一个字符串,该字符串保存uri指定的cookie实例的HTTP cookie头。HTTP头是通过添加与uri关联的每个Cookie的字符串表示来构建的。请注意,字符串的确切格式取决于Cookie所遵循的RFC。与uri关联的所有Cookie实例的字符串组合在一起,并用分号分隔


此字符串的格式不正确,无法用作SetCookies方法的第二个参数。

CookieContainer有两个我遇到的主要问题,无论是设计问题还是我不知道的错误

1) 设置在302 post上的Cookie未被拾取。 范例

解决方案 将autoredirect设置为false,手动执行重定向并自行设置cookie

2) Net对字符串中有逗号的不直接形式的cookie字符串非常挑剔。这实际上是正确的,但有时cookies的日期设置中包含逗号,这会停止所有cookies的设置

解决方案 手动解析cookie字符串并添加您自己。一项可怕的任务。我有一个乱七八糟的hack函数,循环和ifs,但最终的结果是它适用于我迄今为止抛出的所有情况。这并不漂亮,但它完成了任务


不确定以上是你的问题,但可能。如果不是值得思考的话

我的解决方案是:将“UTC”替换为“GMT”。

我的想法是,在我执行GetResponse()之前,实际的POST没有发送到NIC上,但我认为你是对的。谢谢你的快速回复!!我会尝试一下,然后再给你回复。只是更新了代码,但似乎无法修复它。不过谢谢你。据我所知,特雷仍然是对的。我们在ASP.NET中使用IIS,GetCookieHeader返回一个分号分隔的列表,SetCookies不接受该列表。问题似乎出在GetCookieHeader上。对我有用。谢谢。
 Post to site
  302 redirect response
  Load New page which sets cookie