技术开发 频道

实现支持会话的WebClient

    WebClient类是一个很好工具,可以通过指定一个URL,下载文件,或上传和下载数据,在下载文件时还能实现异步下载. 但是使用WebClient访问URL时,是没有会话的,也就是说每一次使WebClient发起请求,都是一次新的会话.举一个例子. 比如:在访问页面B时要判断Session["UserName"]的值是不是空.而Session["UserName"]的值是在页面A中赋值. 如果直接使用WebClient.如下代码
WebClient client = new WebClient(); clinet.DownloadString(@"http://PageA.aspx"); clinet.DownloadString(@"http://PageB.aspx");
    PageB中Session值也是空的.  网上有人提出了这个问题的解决办法,就是使用HttpWebRequest如下:
CookieContainer cc = new CookieContainer(); for(int i=0;i<100;i++) { HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://localhost/AspxApp/MainForm.aspx"); myReq.CookieContainer = cc; HttpWebResponse resp = myReq.GetResponse() as HttpWebResponse; Stream s = resp.GetResponseStream(); StreamReader sr = new StreamReader(s); String text = sr.ReadToEnd(); sr.Close(); s.Close(); }

    这样当然可以解决问题,但是有一个不好地方,就是HttpWebRequest的功能比较弱,只能返回流,下载文件时不能异步,没有进度.
我通过使用Reflector查看了一下WebClient的代码,发现WebClient每次发请求(如DownloadString)时都会调用自己的一个叫GetWebRequest的方法,查MSDN,发现GetWebRequest 方法签名如下

protected virtual WebRequest GetWebRequest ( Uri address )

    也就意味着,如果我们重写这个方法,把CookeContainer给这个WebRequest加上,那么WebClinet就支持会话了. 实现代码如下:

public class HttpWebClient:WebClient { private CookieContainer cookie ; protected override WebRequest GetWebRequest(Uri address) { //throw new Exception(); WebRequest request ; request = base.GetWebRequest(address); //判断是不是HttpWebRequest.只有HttpWebRequest才有此属性 if (request is HttpWebRequest) { HttpWebRequest httpRequest = request as HttpWebRequest; httpRequest.CookieContainer = cookie; } return request; } public HttpWebClient(CookieContainer cookie) { this.cookie = cookie; } }

    调用代码如下:

ttpWebClient httpClient = new HttpWebClient(new CookieContainer()); String s = httpClient.DownloadString(@"http://localhost/TestWS/Default.aspx"); s = httpClient.DownloadString(String.Format(@"http://localhost/TestWS/Test.aspx?Test={0}",s)); Console.WriteLine(s);

 

0
相关文章