随笔 - 30  文章 - 13  评论 - 120  阅读 - 53097

实现支持会话的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
如下
http://blog.joycode.com/yaodong/archive/2004/10/10/35129.aspx
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);

这篇Blog是我在没开VS2005的情况下写的,可能代码会有小的问题编译不能通过之类的,应该无大的问题!希望对大家有用
posted on   Yunanw  阅读(4124)  评论(8编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
< 2007年11月 >
28 29 30 31 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示