我正在开发一个使用WebClient的应用程序.我有这个扩展基本WebClient功能的类:
public class WebClientEx : WebClient
{
private CookieContainer _cookieContainer = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = _cookieContainer;
(request as HttpWebRequest).AllowAutoRedirect = true;
(request as HttpWebRequest).Timeout = 10000;
}
return request;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用WebClientEx登录到站点并请求一些信息.它适用于4.0和4.5,但它不适用于早期版本,如3.5,3.0等.我添加了一些调试代码,在早期版本中,它说cookie容器中有0个cookie,而4.0+表示那里应该是两个饼干.
所以原因可能是早期版本的.NET Framework 在cookie容器中存储cookie时存在一些问题.如何解决?
我已经确认.NET 3.5中的行为与.NET 4.0相比有所不同.使用以下代码进行测试:
Uri sourceUri = new Uri(@"http://www.html-kit.com/tools/cookietester/");
WebClientEx webClientEx = new WebClientEx();
webClientEx.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
webClientEx.UploadString(sourceUri, "cn=MyCookieName&cv=MyCookieValue");
var text = webClientEx.DownloadString(sourceUri);
var doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(new MemoryStream(Encoding.ASCII.GetBytes((text))));
var node = doc.DocumentNode.SelectNodes("//div").Single(n => n.InnerText.StartsWith("\r\nNumber of cookies received:"));
Debug.Assert(int.Parse(node.InnerText.Split(' ')[4]) == 1);
Run Code Online (Sandbox Code Playgroud)
当然,这不能回答你的问题; 但是我没有理由认为行为存在差异,除了说它可能已经在.NET 4.0中得到修复并且修复程序没有被放入.NET 3.5或之前的版本中.
我尝试了类似的东西,HttpWebRequest并遇到了同样的问题(工作在4,但不是之前):
HttpWebRequest webreq = ((HttpWebRequest) (WebRequest.Create(sourceUri)));
CookieContainer cookies = new CookieContainer();
var postdata = Encoding.ASCII.GetBytes("cn=MyCookieName&cv=MyCookieValue");
webreq.CookieContainer = cookies;
webreq.Method = "POST";
webreq.ContentLength = postdata.Length;
webreq.ContentType = "application/x-www-form-urlencoded";
Stream webstream = webreq.GetRequestStream();
webstream.Write(postdata, 0, postdata.Length);
webstream.Close();
using (WebResponse response = webreq.GetResponse())
{
webstream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(webstream))
{
String responseFromServer = reader.ReadToEnd();
var doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(new MemoryStream(Encoding.ASCII.GetBytes((responseFromServer))));
var node =
doc.DocumentNode.SelectNodes("//div").Single(n => n.InnerText.StartsWith("\r\nNumber of cookies received:"));
Debug.Assert(int.Parse(node.InnerText.Split(' ')[4]) == 1);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,HttpWebRequest(WebClient使用)似乎存在问题.这可能是新的,因为我看到人们在4.0发布之前使用这样的代码(可能在3.50之前,他们说它有效.
如果紧急,我建议您与Microsoft支持部门联系.如果您拥有MSDN许可证,则以下链接将详细说明如何使用附带的MSDN支持票证发出支持请求:http://msdn.microsoft.com/en-us/subscriptions/bb266240.aspx 如果您没有MSDN您可以通过以下详细信息联系支持部门:https://support.microsoft.com/oas/default.aspx?Graid = 8291&st = 1&wfxredirect = 1&sd = gn
如果它不那么紧急,那么您可以在http://connect.microsoft.com/VisualStudio上记录该问题,看看您是否得到了解决方法.
我刚刚创建了一个基本的 IHttpHandler 来测试这个类,它似乎可以工作。
<%@ WebHandler Language="C#" Class="CookieTest" %>
using System;
using System.Net;
using System.Web;
public class CookieTest : IHttpHandler
{
public class WebClientEx : WebClient
{
private CookieContainer _cookieContainer = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = _cookieContainer;
(request as HttpWebRequest).AllowAutoRedirect = true;
(request as HttpWebRequest).Timeout = 10000;
}
return request;
}
}
public void ProcessRequest(HttpContext ctxt)
{
ctxt.Response.ContentType = "text/plain";
String cmd = ctxt.Request["cmd"];
if (cmd == "set")
{
ctxt.Response.Cookies.Add(new HttpCookie("test", "test"));
ctxt.Response.Write("Cookie Set: test = test");
}
else if (cmd == "get")
{
ctxt.Response.Write("Cookie Value: test = " + ctxt.Request.Cookies["test"].Value);
}
else
{
// run out tests
WebClientEx wc = new WebClientEx();
ctxt.Response.Write("Running tests on .NET version: " + Environment.Version);
ctxt.Response.Write(Environment.NewLine + Environment.NewLine);
ctxt.Response.Write("Setting Cookie...");
ctxt.Response.Write(Environment.NewLine + Environment.NewLine);
ctxt.Response.Write("Response: " + wc.DownloadString(ctxt.Request.Url.AbsoluteUri + "?cmd=set"));
ctxt.Response.Write(Environment.NewLine + Environment.NewLine);
ctxt.Response.Write("Getting Cookie...");
ctxt.Response.Write(Environment.NewLine + Environment.NewLine);
ctxt.Response.Write("Response: " + wc.DownloadString(ctxt.Request.Url.AbsoluteUri + "?cmd=get"));
ctxt.Response.Write(Environment.NewLine + Environment.NewLine);
}
}
public bool IsReusable
{
get { return true; }
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:
在.NET版本上运行测试:2.0.50727.5456
设置 Cookie...
响应:Cookie 设置:测试 = 测试
获取 Cookie...
响应:Cookie 值:测试 = 测试
您认为这正确吗?