迷你型WebClient

2 篇文章 0 订阅

    对HttpWebRequest/HttpWebResponse进行封装处理,提供方便的接口向互联网发送或接收数据。支持POST urlencode形式的字符串以及mulitpart/form-data形式的二进制或文本数据,支持GET方式获取数据。自动管理Cookie,解决网络访问中难以处理的权限问题。支持gzip,deflate编码数据解压。测试代码见代码后面。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Data;
  5. using System.IO;
  6. using System.Net;
  7. using System.Net.Security;
  8. using System.Security.Cryptography.X509Certificates;
  9. using System.IO.Compression;
  10. using System.Net.Cache;
  11. namespace HttpProc
  12. {
  13.     /// <summary>
  14.     /// 上传数据参数
  15.     /// </summary>
  16.     public class UploadEventArgs : EventArgs
  17.     {
  18.         int bytesSent;
  19.         int totalBytes;
  20.         /// <summary>
  21.         /// 已发送的字节数
  22.         /// </summary>
  23.         public int BytesSent
  24.         {
  25.             get { return bytesSent; }
  26.             set { bytesSent = value; }
  27.         }
  28.         /// <summary>
  29.         /// 总字节数
  30.         /// </summary>
  31.         public int TotalBytes
  32.         {
  33.             get { return totalBytes; }
  34.             set { totalBytes = value; }
  35.         }
  36.     }
  37.     /// <summary>
  38.     /// 下载数据参数
  39.     /// </summary>
  40.     public class DownloadEventArgs : EventArgs
  41.     {
  42.         int bytesReceived;
  43.         int totalBytes;
  44.         byte[] receivedData;
  45.         /// <summary>
  46.         /// 已接收的字节数
  47.         /// </summary>
  48.         public int BytesReceived
  49.         {
  50.             get { return bytesReceived; }
  51.             set { bytesReceived = value; }
  52.         }
  53.         /// <summary>
  54.         /// 总字节数
  55.         /// </summary>
  56.         public int TotalBytes
  57.         {
  58.             get { return totalBytes; }
  59.             set { totalBytes = value; }
  60.         }
  61.         /// <summary>
  62.         /// 当前缓冲区接收的数据
  63.         /// </summary>
  64.         public byte[] ReceivedData
  65.         {
  66.             get { return receivedData; }
  67.             set { receivedData = value; }
  68.         }
  69.     }
  70.     public class WebClient
  71.     {
  72.         Encoding encoding = Encoding.Default;
  73.         string respHtml = "";
  74.         WebProxy proxy;
  75.         static CookieContainer cc;
  76.         WebHeaderCollection requestHeaders;
  77.         WebHeaderCollection responseHeaders;
  78.         int bufferSize = 15240;
  79.         public event EventHandler<UploadEventArgs> UploadProgressChanged;
  80.         public event EventHandler<DownloadEventArgs> DownloadProgressChanged;
  81.         static WebClient()
  82.         {
  83.             LoadCookiesFromDisk();
  84.         }
  85.         /// <summary>
  86.         /// 创建WebClient的实例
  87.         /// </summary>
  88.         public WebClient()
  89.         {
  90.             requestHeaders = new WebHeaderCollection();
  91.             responseHeaders = new WebHeaderCollection();
  92.         }
  93.         /// <summary>
  94.         /// 设置发送和接收的数据缓冲大小
  95.         /// </summary>
  96.         public int BufferSize
  97.         {
  98.             get { return bufferSize; }
  99.             set { bufferSize = value; }
  100.         }
  101.         /// <summary>
  102.         /// 获取响应头集合
  103.         /// </summary>
  104.         public WebHeaderCollection ResponseHeaders
  105.         {
  106.             get { return responseHeaders; }
  107.         }
  108.         /// <summary>
  109.         /// 获取请求头集合
  110.         /// </summary>
  111.         public WebHeaderCollection RequestHeaders
  112.         {
  113.             get { return requestHeaders; }
  114.         }
  115.         /// <summary>
  116.         /// 获取或设置代理
  117.         /// </summary>
  118.         public WebProxy Proxy
  119.         {
  120.             get { return proxy; }
  121.             set { proxy = value; }
  122.         }
  123.         /// <summary>
  124.         /// 获取或设置请求与响应的文本编码方式
  125.         /// </summary>
  126.         public Encoding Encoding
  127.         {
  128.             get { return encoding; }
  129.             set { encoding = value; }
  130.         }
  131.         /// <summary>
  132.         /// 获取或设置响应的html代码
  133.         /// </summary>
  134.         public string RespHtml
  135.         {
  136.             get { return respHtml; }
  137.             set { respHtml = value; }
  138.         }
  139.         /// <summary>
  140.         /// 获取或设置与请求关联的Cookie容器
  141.         /// </summary>
  142.         public CookieContainer CookieContainer
  143.         {
  144.             get { return cc; }
  145.             set { cc = value; }
  146.         }
  147.         /// <summary>
  148.         ///  获取网页源代码
  149.         /// </summary>
  150.         /// <param name="url">网址</param>
  151.         /// <returns></returns>
  152.         public string GetHtml(string url)
  153.         {
  154.             HttpWebRequest request = CreateRequest(url, "GET");
  155.             respHtml = encoding.GetString(GetData(request));
  156.             return respHtml;
  157.         }
  158.         /// <summary>
  159.         /// 下载文件
  160.         /// </summary>
  161.         /// <param name="url">文件URL地址</param>
  162.         /// <param name="filename">文件保存完整路径</param>
  163.         public void DownloadFile(string url, string filename)
  164.         {
  165.             FileStream fs = null;
  166.             try
  167.             {
  168.                 HttpWebRequest request = CreateRequest(url, "GET");
  169.                 byte[] data = GetData(request);
  170.                 fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
  171.                 fs.Write(data, 0, data.Length);
  172.             }
  173.             finally
  174.             {
  175.                 if (fs != null) fs.Close();
  176.             }
  177.         }
  178.         /// <summary>
  179.         /// 从指定URL下载数据
  180.         /// </summary>
  181.         /// <param name="url">网址</param>
  182.         /// <returns></returns>
  183.         public byte[] GetData(string url)
  184.         {
  185.             HttpWebRequest request = CreateRequest(url, "GET");
  186.             return GetData(request);
  187.         }
  188.         /// <summary>
  189.         /// 向指定URL发送文本数据
  190.         /// </summary>
  191.         /// <param name="url">网址</param>
  192.         /// <param name="postData">urlencode编码的文本数据</param>
  193.         /// <returns></returns>
  194.         public string Post(string url, string postData)
  195.         {
  196.             byte[] data = encoding.GetBytes(postData);
  197.             return Post(url, data);
  198.         }
  199.         /// <summary>
  200.         /// 向指定URL发送字节数据
  201.         /// </summary>
  202.         /// <param name="url">网址</param>
  203.         /// <param name="postData">发送的字节数组</param>
  204.         /// <returns></returns>
  205.         public string Post(string url, byte[] postData)
  206.         {
  207.             HttpWebRequest request = CreateRequest(url, "POST");
  208.             request.ContentType = "application/x-www-form-urlencoded";
  209.             request.ContentLength = postData.Length;
  210.             request.KeepAlive = true;
  211.             PostData(request, postData);
  212.             respHtml = encoding.GetString(GetData(request));
  213.             return respHtml;
  214.         }
  215.         /// <summary>
  216.         /// 向指定网址发送mulitpart编码的数据
  217.         /// </summary>
  218.         /// <param name="url">网址</param>
  219.         /// <param name="mulitpartForm">mulitpart form data</param>
  220.         /// <returns></returns>
  221.         public string Post(string url, MultipartForm mulitpartForm)
  222.         {
  223.             HttpWebRequest request = CreateRequest(url, "POST");
  224.             request.ContentType = mulitpartForm.ContentType;
  225.             request.ContentLength = mulitpartForm.FormData.Length;
  226.             request.KeepAlive = true;
  227.             PostData(request, mulitpartForm.FormData);
  228.             respHtml = encoding.GetString(GetData(request));
  229.             return respHtml;
  230.         }
  231.         /// <summary>
  232.         /// 读取请求返回的数据
  233.         /// </summary>
  234.         /// <param name="request">请求对象</param>
  235.         /// <returns></returns>
  236.         private byte[] GetData(HttpWebRequest request)
  237.         {
  238.             HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  239.             Stream stream = response.GetResponseStream();
  240.             responseHeaders = response.Headers;
  241.             SaveCookiesToDisk();
  242.             DownloadEventArgs args = new DownloadEventArgs();
  243.             if (responseHeaders[HttpResponseHeader.ContentLength] != null)
  244.                 args.TotalBytes = Convert.ToInt32(responseHeaders[HttpResponseHeader.ContentLength]);
  245.             MemoryStream ms = new MemoryStream();
  246.             int count = 0;
  247.             byte[] buf = new byte[bufferSize];
  248.             while ((count = stream.Read(buf, 0, buf.Length)) > 0)
  249.             {
  250.                 ms.Write(buf, 0, count);
  251.                 if (this.DownloadProgressChanged != null)
  252.                 {
  253.                     args.BytesReceived += count;
  254.                     args.ReceivedData = new byte[count];
  255.                     Array.Copy(buf, args.ReceivedData, count);
  256.                     this.DownloadProgressChanged(this, args);
  257.                 }
  258.             }
  259.             stream.Close();
  260.             //解压
  261.             if (ResponseHeaders[HttpResponseHeader.ContentEncoding] != null)
  262.             {
  263.                 MemoryStream msTemp = new MemoryStream();
  264.                 count = 0;
  265.                 buf = new byte[100];
  266.                 switch (ResponseHeaders[HttpResponseHeader.ContentEncoding].ToLower())
  267.                 {
  268.                     case "gzip":
  269.                         GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
  270.                         while ((count = gzip.Read(buf, 0, buf.Length)) > 0)
  271.                         {
  272.                             msTemp.Write(buf, 0, count);
  273.                         }
  274.                         return msTemp.ToArray();
  275.                     case "deflate":
  276.                         DeflateStream deflate = new DeflateStream(ms, CompressionMode.Decompress);
  277.                         while ((count = deflate.Read(buf, 0, buf.Length)) > 0)
  278.                         {
  279.                             msTemp.Write(buf, 0, count);
  280.                         }
  281.                         return msTemp.ToArray();
  282.                     default:
  283.                         break;
  284.                 }
  285.             }
  286.             return ms.ToArray();
  287.         }
  288.         /// <summary>
  289.         /// 发送请求数据
  290.         /// </summary>
  291.         /// <param name="request">请求对象</param>
  292.         /// <param name="postData">请求发送的字节数组</param>
  293.         private void PostData(HttpWebRequest request, byte[] postData)
  294.         {
  295.             int offset = 0;
  296.             int sendBufferSize = bufferSize;
  297.             int remainBytes = 0;
  298.             Stream stream = request.GetRequestStream();
  299.             UploadEventArgs args = new UploadEventArgs();
  300.             args.TotalBytes = postData.Length;
  301.             while ((remainBytes = postData.Length - offset) > 0)
  302.             {
  303.                 if (sendBufferSize > remainBytes) sendBufferSize = remainBytes;
  304.                 stream.Write(postData, offset, sendBufferSize);
  305.                 offset += sendBufferSize;
  306.                 if (this.UploadProgressChanged != null)
  307.                 {
  308.                     args.BytesSent = offset;
  309.                     this.UploadProgressChanged(this, args);
  310.                 }
  311.             }
  312.             stream.Close();
  313.         }
  314.         /// <summary>
  315.         /// 创建HTTP请求
  316.         /// </summary>
  317.         /// <param name="url">URL地址</param>
  318.         /// <returns></returns>
  319.         private HttpWebRequest CreateRequest(string url, string method)
  320.         {
  321.             Uri uri = new Uri(url);
  322.             if (uri.Scheme == "https")
  323.                 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(this.CheckValidationResult);
  324.             // Set a default policy level for the "http:" and "https" schemes.
  325.             HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Revalidate);
  326.             HttpWebRequest.DefaultCachePolicy = policy;
  327.             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
  328.             request.AllowAutoRedirect = false;
  329.             request.AllowWriteStreamBuffering = false;
  330.             request.Method = method;
  331.             if (proxy != null) request.Proxy = proxy;
  332.             request.CookieContainer = cc;
  333.             foreach (string key in requestHeaders.Keys)
  334.             {
  335.                 request.Headers.Add(key, requestHeaders[key]);
  336.             }
  337.             requestHeaders.Clear();
  338.             return request;
  339.         }
  340.         private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
  341.         {
  342.             return true;
  343.         }
  344.         /// <summary>
  345.         /// 将Cookie保存到磁盘
  346.         /// </summary>
  347.         private static void SaveCookiesToDisk()
  348.         {
  349.             string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "//webclient.cookie";
  350.             FileStream fs = null;
  351.             try
  352.             {
  353.                 fs = new FileStream(cookieFile, FileMode.Create);
  354.                 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  355.                 formater.Serialize(fs, cc);
  356.             }
  357.             finally
  358.             {
  359.                 if (fs != null) fs.Close();
  360.             }
  361.         }
  362.         /// <summary>
  363.         /// 从磁盘加载Cookie
  364.         /// </summary>
  365.         private static void LoadCookiesFromDisk()
  366.         {
  367.             cc = new CookieContainer();
  368.             string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "//webclient.cookie";
  369.             if (!File.Exists(cookieFile))
  370.                 return;
  371.             FileStream fs = null;
  372.             try
  373.             {
  374.                 fs = new FileStream(cookieFile, FileMode.Open, FileAccess.Read, FileShare.Read);
  375.                 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  376.                 cc = (CookieContainer)formater.Deserialize(fs);
  377.             }
  378.             finally
  379.             {
  380.                 if (fs != null) fs.Close();
  381.             }
  382.         }
  383.     }
  384.     /// <summary>
  385.     /// 对文件和文本数据进行Multipart形式的编码
  386.     /// </summary>
  387.     public class MultipartForm
  388.     {
  389.         private Encoding encoding;
  390.         private MemoryStream ms;
  391.         private string boundary;
  392.         private byte[] formData;
  393.         /// <summary>
  394.         /// 获取编码后的字节数组
  395.         /// </summary>
  396.         public byte[] FormData
  397.         {
  398.             get
  399.             {
  400.                 if (formData == null)
  401.                 {
  402.                     byte[] buffer = encoding.GetBytes("--" + this.boundary + "--/r/n");
  403.                     ms.Write(buffer, 0, buffer.Length);
  404.                     formData = ms.ToArray();
  405.                 }
  406.                 return formData;
  407.             }
  408.         }
  409.         /// <summary>
  410.         /// 获取此编码内容的类型
  411.         /// </summary>
  412.         public string ContentType
  413.         {
  414.             get { return string.Format("multipart/form-data; boundary={0}"this.boundary); }
  415.         }
  416.         /// <summary>
  417.         /// 获取或设置对字符串采用的编码类型
  418.         /// </summary>
  419.         public Encoding StringEncoding
  420.         {
  421.             set { encoding = value; }
  422.             get { return encoding; }
  423.         }
  424.         /// <summary>
  425.         /// 实例化
  426.         /// </summary>
  427.         public MultipartForm()
  428.         {
  429.             boundary = string.Format("--{0}--", Guid.NewGuid());
  430.             ms = new MemoryStream();
  431.             encoding = Encoding.Default;
  432.         }
  433.         /// <summary>
  434.         /// 添加一个文件
  435.         /// </summary>
  436.         /// <param name="name">文件域名称</param>
  437.         /// <param name="filename">文件的完整路径</param>
  438.         public void AddFlie(string name, string filename)
  439.         {
  440.             if (!File.Exists(filename))
  441.                 throw new FileNotFoundException("尝试添加不存在的文件。", filename);
  442.             FileStream fs = null;
  443.             byte[] fileData ={ };
  444.             try
  445.             {
  446.                 fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
  447.                 fileData = new byte[fs.Length];
  448.                 fs.Read(fileData, 0, fileData.Length);
  449.                 this.AddFlie(name, Path.GetFileName(filename), fileData, fileData.Length);
  450.             }
  451.             catch (Exception)
  452.             {
  453.                 throw;
  454.             }
  455.             finally
  456.             {
  457.                 if (fs != null) fs.Close();
  458.             }
  459.         }
  460.         /// <summary>
  461.         /// 添加一个文件
  462.         /// </summary>
  463.         /// <param name="name">文件域名称</param>
  464.         /// <param name="filename">文件名</param>
  465.         /// <param name="fileData">文件二进制数据</param>
  466.         /// <param name="dataLength">二进制数据大小</param>
  467.         public void AddFlie(string name, string filename, byte[] fileData, int dataLength)
  468.         {
  469.             if (dataLength <= 0 || dataLength > fileData.Length)
  470.             {
  471.                 dataLength = fileData.Length;
  472.             }
  473.             StringBuilder sb = new StringBuilder();
  474.             sb.AppendFormat("--{0}/r/n"this.boundary);
  475.             sb.AppendFormat("Content-Disposition: form-data; name=/"{0}/";filename=/"{1}/"/r/n", name, filename);
  476.             sb.AppendFormat("Content-Type: {0}/r/n"this.GetContentType(filename));
  477.             sb.Append("/r/n");
  478.             byte[] buf = encoding.GetBytes(sb.ToString());
  479.             ms.Write(buf, 0, buf.Length);
  480.             ms.Write(fileData, 0, dataLength);
  481.             byte[] crlf = encoding.GetBytes("/r/n");
  482.             ms.Write(crlf, 0, crlf.Length);
  483.         }
  484.         /// <summary>
  485.         /// 添加字符串
  486.         /// </summary>
  487.         /// <param name="name">文本域名称</param>
  488.         /// <param name="value">文本值</param>
  489.         public void AddString(string name, string value)
  490.         {
  491.             StringBuilder sb = new StringBuilder();
  492.             sb.AppendFormat("--{0}/r/n"this.boundary);
  493.             sb.AppendFormat("Content-Disposition: form-data; name=/"{0}/"/r/n", name);
  494.             sb.Append("/r/n");
  495.             sb.AppendFormat("{0}/r/n", value);
  496.             byte[] buf = encoding.GetBytes(sb.ToString());
  497.             ms.Write(buf, 0, buf.Length);
  498.         }
  499.         /// <summary>
  500.         /// 从注册表获取文件类型
  501.         /// </summary>
  502.         /// <param name="filename">包含扩展名的文件名</param>
  503.         /// <returns>如:application/stream</returns>
  504.         private string GetContentType(string filename)
  505.         {
  506.             Microsoft.Win32.RegistryKey fileExtKey = null; ;
  507.             string contentType = "application/stream";
  508.             try
  509.             {
  510.                 fileExtKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filename));
  511.                 contentType = fileExtKey.GetValue("Content Type", contentType).ToString();
  512.             }
  513.             finally
  514.             {
  515.                 if (fileExtKey != null) fileExtKey.Close();
  516.             }
  517.             return contentType;
  518.         }
  519.     }
  520. }

使用实例:

  1.    class Test
  2.     {
  3.         public static void Test1()
  4.         {
  5.             HttpProc.WebClient c = new HttpProc.WebClient();
  6.             c.DownloadProgressChanged += new EventHandler<HttpProc.DownloadEventArgs>(c_DownloadProgressChanged);
  7.             c.UploadProgressChanged += new EventHandler<HttpProc.UploadEventArgs>(c_UploadProgressChanged);
  8.             
  9.             //登录百度空间
  10.             c.Post("https://passport.baidu.com/?login""username=hddo&password=**********");
  11.             if (c.RespHtml.Contains("passport.baidu.com"))
  12.             {
  13.                 //登录成功
  14.             }
  15.             //向百度相册上传图片
  16.             HttpProc.MultipartForm mf = new HttpProc.MultipartForm();
  17.             mf.AddString("BrowserType""1");
  18.             mf.AddString("spPhotoText0""10086");
  19.             mf.AddString("spAlbumName""默认相册");
  20.             mf.AddString("spMaxSize""1600");
  21.             mf.AddString("spQuality""90");
  22.             mf.AddFlie("file1""D://Blue hills2.jpg");
  23.             c.Post("http://hiup.baidu.com/hddo/upload", mf);
  24.             if (c.RespHtml.Contains("submit(0,0)"))
  25.             {
  26.                 //上传图片成功
  27.             }
  28.         }
  29.         static void c_UploadProgressChanged(object sender, HttpProc.UploadEventArgs e)
  30.         {
  31.             //显示上传进度
  32.         }
  33.         static void c_DownloadProgressChanged(object sender, HttpProc.DownloadEventArgs e)
  34.         {
  35.             //显示下载进度
  36.         }
  37.     }

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值