这两天在处理一个模拟请求 腾讯网站的 任务
发现一个 诡异的事情,同样的代码 在.NET Framework 4.0下 完美运行,但是只要项目改成2.0 设置的CookieContainer 设置的 Cookie 就似乎无效了,一直提示请登录
代码如下:
CookieContainer cc = new CookieContainer();
string strCookie = "登录后从目标网站获取的cookie"; string[] cookstr = strCookie.Split(';'); foreach (string str in cookstr) { string[] cookieNameValue = str.Split('='); Cookie ck = new Cookie(cookieNameValue[0].Trim().ToString(), cookieNameValue[1].Trim().ToString()); ck.Domain = "qq.com"; } NetHelper net = new NetHelper(); net.Url = "请求的URL"; net.Method = RequestMethod.GET; net.Cookies = cc; net.SendRequest();
这是一段非常简单的 设置cookie的代码 在2.0框架下 一直 提示要登录 在代码不变得情况下 换成4.0框架 就没毛病
搜索再三,才发现这是.NET 4.0以下框架的CookieContainer的一个BUG 在某些情况下 cookie设置的 domain 没有成功 才导致 发送请求的时候 少发送了一些 cookie
1 internal static void OnSendingHeaders(HttpWebRequest httpWebRequest) 2 { 3 try 4 { 5 if (httpWebRequest.CookieContainer != null) 6 { 7 string str; 8 httpWebRequest.Headers.RemoveInternal("Cookie"); 9 string cookieHeader = httpWebRequest.CookieContainer.GetCookieHeader(httpWebRequest.Address, out str); 10 if (cookieHeader.Length > 0) 11 { 12 httpWebRequest.Headers["Cookie"] = cookieHeader; 13 } 14 } 15 } 16 catch 17 { 18 } 19 }
这是从网上 看到的详细代码
解决方案:
1.不要调用CookieContainer的 Add(cookie) 方法,改为调用Add(Uri uri, Cookie cookie),并且在new 一个cookie的时候 一定要给 这个cookie 设置Domain属性
2.此方法参考别的博主的写的,但是本人尝试 并没有用,此方法可以供在方法一失效时,再次尝试
private void BugFix_CookieDomain(CookieContainer cookieContainer) { System.Type _ContainerType = typeof(CookieContainer); Hashtable table = (Hashtable)_ContainerType.InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cookieContainer, new object[] { }); ArrayList keys = new ArrayList(table.Keys); foreach (string keyObj in keys) { string key = (keyObj as string); if (key[0] == '.') { string newKey = key.Remove(0, 1); table[newKey] = table[keyObj]; } } }
每次调用将cookie设置到CookieContainer中 都调用此方法