zoukankan      html  css  js  c++  java
  • C# 实现http协议GET、POST请求

    对HttpWebRequest/HttpWebResponse 进行封装处理,提供方便的接口向互联网发送或接收数据。支持POST urlencode形式的字符串以及mulitpart/form-data形式的二进制或文本数据,支持GET方式获取数据。自动管理Cookie,解 决网络访问中难以处理的权限问题。支持gzip,deflate编码数据解压。测试代码见代码后面。

    using System; 
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.IO;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.IO.Compression;
    using System.Net.Cache;

    namespace HttpProc
    {
    /// <summary>
    /// 上传数据参数
    /// </summary>
    public class UploadEventArgs : EventArgs
    {
    int bytesSent;
    int totalBytes;
    /// <summary>
    /// 已发送的字节数
    /// </summary>
    public int BytesSent
    {
    get { return bytesSent; }
    set { bytesSent = value; }
    }
    /// <summary>
    /// 总字节数
    /// </summary>
    public int TotalBytes
    {
    get { return totalBytes; }
    set { totalBytes = value; }
    }
    }
    /// <summary>
    /// 下载数据参数
    /// </summary>
    public class DownloadEventArgs : EventArgs
    {
    int bytesReceived;
    int totalBytes;
    byte[] receivedData;
    /// <summary>
    /// 已接收的字节数
    /// </summary>
    public int BytesReceived
    {
    get { return bytesReceived; }
    set { bytesReceived = value; }
    }
    /// <summary>
    /// 总字节数
    /// </summary>
    public int TotalBytes
    {
    get { return totalBytes; }
    set { totalBytes = value; }
    }
    /// <summary>
    /// 当前缓冲区接收的数据
    /// </summary>
    public byte[] ReceivedData
    {
    get { return receivedData; }
    set { receivedData = value; }
    }
    }

    public class WebClient
    {
    Encoding encoding = Encoding.Default;
    string respHtml = "";
    WebProxy proxy;
    static CookieContainer cc;
    WebHeaderCollection requestHeaders;
    WebHeaderCollection responseHeaders;
    int bufferSize = 15240;
    public event EventHandler<UploadEventArgs> UploadProgressChanged;
    public event EventHandler<DownloadEventArgs> DownloadProgressChanged;
    static WebClient()
    {
    LoadCookiesFromDisk();
    }
    /// <summary>
    /// 创建WebClient的实例
    /// </summary>
    public WebClient()
    {
    requestHeaders = new WebHeaderCollection();
    responseHeaders = new WebHeaderCollection();
    }
    /// <summary>
    /// 设置发送和接收的数据缓冲大小
    /// </summary>
    public int BufferSize
    {
    get { return bufferSize; }
    set { bufferSize = value; }
    }
    /// <summary>
    /// 获取响应头集合
    /// </summary>
    public WebHeaderCollection ResponseHeaders
    {
    get { return responseHeaders; }
    }
    /// <summary>
    /// 获取请求头集合
    /// </summary>
    public WebHeaderCollection RequestHeaders
    {
    get { return requestHeaders; }
    }
    /// <summary>
    /// 获取或设置代理
    /// </summary>
    public WebProxy Proxy
    {
    get { return proxy; }
    set { proxy = value; }
    }
    /// <summary>
    /// 获取或设置请求与响应的文本编码方式
    /// </summary>
    public Encoding Encoding
    {
    get { return encoding; }
    set { encoding = value; }
    }
    /// <summary>
    /// 获取或设置响应的html代码
    /// </summary>
    public string RespHtml
    {
    get { return respHtml; }
    set { respHtml = value; }
    }
    /// <summary>
    /// 获取或设置与请求关联的Cookie容器
    /// </summary>
    public CookieContainer CookieContainer
    {
    get { return cc; }
    set { cc = value; }
    }
    /// <summary>
    /// 获取网页源代码
    /// </summary>
    /// <param name="url">网址</param>
    /// <returns></returns>
    public string GetHtml(string url)
    {
    HttpWebRequest request = CreateRequest(url, "GET");
    respHtml = encoding.GetString(GetData(request));
    return respHtml;
    }
    /// <summary>
    /// 下载文件
    /// </summary>
    /// <param name="url">文件URL地址</param>
    /// <param name="filename">文件保存完整路径</param>
    public void DownloadFile(string url, string filename)
    {
    FileStream fs = null;
    try
    {
    HttpWebRequest request = CreateRequest(url, "GET");
    byte[] data = GetData(request);
    fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
    fs.Write(data, 0, data.Length);
    }
    finally
    {
    if (fs != null) fs.Close();
    }
    }
    /// <summary>
    /// 从指定URL下载数据
    /// </summary>
    /// <param name="url">网址</param>
    /// <returns></returns>
    public byte[] GetData(string url)
    {
    HttpWebRequest request = CreateRequest(url, "GET");
    return GetData(request);
    }
    /// <summary>
    /// 向指定URL发送文本数据
    /// </summary>
    /// <param name="url">网址</param>
    /// <param name="postData">urlencode编码的文本数据</param>
    /// <returns></returns>
    public string Post(string url, string postData)
    {
    byte[] data = encoding.GetBytes(postData);
    return Post(url, data);
    }
    /// <summary>
    /// 向指定URL发送字节数据
    /// </summary>
    /// <param name="url">网址</param>
    /// <param name="postData">发送的字节数组</param>
    /// <returns></returns>
    public string Post(string url, byte[] postData)
    {
    HttpWebRequest request = CreateRequest(url, "POST");
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = postData.Length;
    request.KeepAlive = true;
    PostData(request, postData);
    respHtml = encoding.GetString(GetData(request));
    return respHtml;
    }
    /// <summary>
    /// 向指定网址发送mulitpart编码的数据
    /// </summary>
    /// <param name="url">网址</param>
    /// <param name="mulitpartForm">mulitpart form data</param>
    /// <returns></returns>
    public string Post(string url, MultipartForm mulitpartForm)
    {
    HttpWebRequest request = CreateRequest(url, "POST");
    request.ContentType = mulitpartForm.ContentType;
    request.ContentLength = mulitpartForm.FormData.Length;
    request.KeepAlive = true;
    PostData(request, mulitpartForm.FormData);
    respHtml = encoding.GetString(GetData(request));
    return respHtml;
    }
    /// <summary>
    /// 读取请求返回的数据
    /// </summary>
    /// <param name="request">请求对象</param>
    /// <returns></returns>
    private byte[] GetData(HttpWebRequest request)
    {
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream stream = response.GetResponseStream();
    responseHeaders = response.Headers;
    SaveCookiesToDisk();

    DownloadEventArgs args = new DownloadEventArgs();
    if (responseHeaders[HttpResponseHeader.ContentLength] != null)
    args.TotalBytes = Convert.ToInt32(responseHeaders[HttpResponseHeader.ContentLength]);

    MemoryStream ms = new MemoryStream();
    int count = 0;
    byte[] buf = new byte[bufferSize];
    while ((count = stream.Read(buf, 0, buf.Length)) > 0)
    {
    ms.Write(buf, 0, count);
    if (this.DownloadProgressChanged != null)
    {
    args.BytesReceived += count;
    args.ReceivedData = new byte[count];
    Array.Copy(buf, args.ReceivedData, count);
    this.DownloadProgressChanged(this, args);
    }
    }
    stream.Close();
    //解压
    if (ResponseHeaders[HttpResponseHeader.ContentEncoding] != null)
    {
    MemoryStream msTemp = new MemoryStream();
    count = 0;
    buf = new byte[100];
    switch (ResponseHeaders[HttpResponseHeader.ContentEncoding].ToLower())
    {
    case "gzip":
    GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
    while ((count = gzip.Read(buf, 0, buf.Length)) > 0)
    {
    msTemp.Write(buf, 0, count);
    }
    return msTemp.ToArray();
    case "deflate":
    DeflateStream deflate = new DeflateStream(ms, CompressionMode.Decompress);
    while ((count = deflate.Read(buf, 0, buf.Length)) > 0)
    {
    msTemp.Write(buf, 0, count);
    }
    return msTemp.ToArray();
    default:
    break;
    }
    }
    return ms.ToArray();
    }
    /// <summary>
    /// 发送请求数据
    /// </summary>
    /// <param name="request">请求对象</param>
    /// <param name="postData">请求发送的字节数组</param>
    private void PostData(HttpWebRequest request, byte[] postData)
    {
    int offset = 0;
    int sendBufferSize = bufferSize;
    int remainBytes = 0;
    Stream stream = request.GetRequestStream();
    UploadEventArgs args = new UploadEventArgs();
    args.TotalBytes = postData.Length;
    while ((remainBytes = postData.Length - offset) > 0)
    {
    if (sendBufferSize > remainBytes) sendBufferSize = remainBytes;
    stream.Write(postData, offset, sendBufferSize);
    offset += sendBufferSize;
    if (this.UploadProgressChanged != null)
    {
    args.BytesSent = offset;
    this.UploadProgressChanged(this, args);
    }
    }
    stream.Close();
    }
    /// <summary>
    /// 创建HTTP请求
    /// </summary>
    /// <param name="url">URL地址</param>
    /// <returns></returns>
    private HttpWebRequest CreateRequest(string url, string method)
    {
    Uri uri = new Uri(url);

    if (uri.Scheme == "https")
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(this.CheckValidationResult);

    // Set a default policy level for the "http:" and "https" schemes.
    HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Revalidate);
    HttpWebRequest.DefaultCachePolicy = policy;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AllowAutoRedirect = false;
    request.AllowWriteStreamBuffering = false;
    request.Method = method;
    if (proxy != null) request.Proxy = proxy;
    request.CookieContainer = cc;
    foreach (string key in requestHeaders.Keys)
    {
    request.Headers.Add(key, requestHeaders[key]);
    }
    requestHeaders.Clear();
    return request;
    }
    private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
    {
    return true;
    }
    /// <summary>
    /// 将Cookie保存到磁盘
    /// </summary>
    private static void SaveCookiesToDisk()
    {
    string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "\\webclient.cookie";
    FileStream fs = null;
    try
    {
    fs = new FileStream(cookieFile, FileMode.Create);
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    formater.Serialize(fs, cc);
    }
    finally
    {
    if (fs != null) fs.Close();
    }
    }
    /// <summary>
    /// 从磁盘加载Cookie
    /// </summary>
    private static void LoadCookiesFromDisk()
    {
    cc = new CookieContainer();
    string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "\\webclient.cookie";
    if (!File.Exists(cookieFile))
    return;
    FileStream fs = null;
    try
    {
    fs = new FileStream(cookieFile, FileMode.Open, FileAccess.Read, FileShare.Read);
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    cc = (CookieContainer)formater.Deserialize(fs);
    }
    finally
    {
    if (fs != null) fs.Close();
    }
    }
    }





    /// <summary>
    /// 对文件和文本数据进行Multipart形式的编码
    /// </summary>
    public class MultipartForm
    {
    private Encoding encoding;
    private MemoryStream ms;
    private string boundary;
    private byte[] formData;
    /// <summary>
    /// 获取编码后的字节数组
    /// </summary>
    public byte[] FormData
    {
    get
    {
    if (formData == null)
    {
    byte[] buffer = encoding.GetBytes("--" + this.boundary + "--\r\n");
    ms.Write(buffer, 0, buffer.Length);
    formData = ms.ToArray();
    }
    return formData;
    }
    }
    /// <summary>
    /// 获取此编码内容的类型
    /// </summary>
    public string ContentType
    {
    get { return string.Format("multipart/form-data; boundary={0}", this.boundary); }
    }
    /// <summary>
    /// 获取或设置对字符串采用的编码类型
    /// </summary>
    public Encoding StringEncoding
    {
    set { encoding = value; }
    get { return encoding; }
    }
    /// <summary>
    /// 实例化
    /// </summary>
    public MultipartForm()
    {
    boundary = string.Format("--{0}--", Guid.NewGuid());
    ms = new MemoryStream();
    encoding = Encoding.Default;
    }
    /// <summary>
    /// 添加一个文件
    /// </summary>
    /// <param name="name">文件域名称</param>
    /// <param name="filename">文件的完整路径</param>
    public void AddFlie(string name, string filename)
    {
    if (!File.Exists(filename))
    throw new FileNotFoundException("尝试添加不存在的文件。", filename);
    FileStream fs = null;
    byte[] fileData ={ };
    try
    {
    fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
    fileData = new byte[fs.Length];
    fs.Read(fileData, 0, fileData.Length);
    this.AddFlie(name, Path.GetFileName(filename), fileData, fileData.Length);
    }
    catch (Exception)
    {
    throw;
    }
    finally
    {
    if (fs != null) fs.Close();
    }
    }
    /// <summary>
    /// 添加一个文件
    /// </summary>
    /// <param name="name">文件域名称</param>
    /// <param name="filename">文件名</param>
    /// <param name="fileData">文件二进制数据</param>
    /// <param name="dataLength">二进制数据大小</param>
    public void AddFlie(string name, string filename, byte[] fileData, int dataLength)
    {
    if (dataLength <= 0 || dataLength > fileData.Length)
    {
    dataLength = fileData.Length;
    }
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("--{0}\r\n", this.boundary);
    sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\n", name, filename);
    sb.AppendFormat("Content-Type: {0}\r\n", this.GetContentType(filename));
    sb.Append("\r\n");
    byte[] buf = encoding.GetBytes(sb.ToString());
    ms.Write(buf, 0, buf.Length);
    ms.Write(fileData, 0, dataLength);
    byte[] crlf = encoding.GetBytes("\r\n");
    ms.Write(crlf, 0, crlf.Length);
    }
    /// <summary>
    /// 添加字符串
    /// </summary>
    /// <param name="name">文本域名称</param>
    /// <param name="value">文本值</param>
    public void AddString(string name, string value)
    {
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("--{0}\r\n", this.boundary);
    sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"\r\n", name);
    sb.Append("\r\n");
    sb.AppendFormat("{0}\r\n", value);
    byte[] buf = encoding.GetBytes(sb.ToString());
    ms.Write(buf, 0, buf.Length);
    }
    /// <summary>
    /// 从注册表获取文件类型
    /// </summary>
    /// <param name="filename">包含扩展名的文件名</param>
    /// <returns>如:application/stream</returns>
    private string GetContentType(string filename)
    {
    Microsoft.Win32.RegistryKey fileExtKey = null; ;
    string contentType = "application/stream";
    try
    {
    fileExtKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filename));
    contentType = fileExtKey.GetValue("Content Type", contentType).ToString();
    }
    finally
    {
    if (fileExtKey != null) fileExtKey.Close();
    }
    return contentType;
    }
    }
    }

    使用实例:

    class Test 
    {
    public static void Test1()
    {
    HttpProc.WebClient c = new HttpProc.WebClient();
    c.DownloadProgressChanged += new EventHandler<HttpProc.DownloadEventArgs>(c_DownloadProgressChanged);
    c.UploadProgressChanged += new EventHandler<HttpProc.UploadEventArgs>(c_UploadProgressChanged);

    //登录百度空间
    c.Post("https://passport.baidu.com/?login", "username=hddo&password=**********");
    if (c.RespHtml.Contains("passport.baidu.com"))
    {
    //登录成功
    }

    //向百度相册上传图片
    HttpProc.MultipartForm mf = new HttpProc.MultipartForm();
    mf.AddString("BrowserType", "1");
    mf.AddString("spPhotoText0", "10086");
    mf.AddString("spAlbumName", "默认相册");
    mf.AddString("spMaxSize", "1600");
    mf.AddString("spQuality", "90");
    mf.AddFlie("file1", "D:\\Blue hills2.jpg");
    c.Post("http://hiup.baidu.com/hddo/upload", mf);
    if (c.RespHtml.Contains("submit(0,0)"))
    {
    //上传图片成功
    }

    }

    static void c_UploadProgressChanged(object sender, HttpProc.UploadEventArgs e)
    {
    //显示上传进度
    }

    static void c_DownloadProgressChanged(object sender, HttpProc.DownloadEventArgs e)
    {
    //显示下载进度
    }

    }
    转自:http://hi.baidu.com/¾ÓÖÛ/blog/item/48ef8a76b2b09a13b151b96a.html
  • 相关阅读:
    asp 中response.write
    英语学习的几个概念
    javascript学习(一)
    什么是教学大纲?
    桌面快速启动栏里的“显示桌面”没有的解决办法
    gridview的编辑功能为什么不能用?
    asp中添加数据的两种方法(access数据库)
    CSS入门
    从全国教育科学研究“十一五”规划(教育信息技术)看教育技术的研究趋势
    软件工程
  • 原文地址:https://www.cnblogs.com/gyxdbk/p/1701166.html
Copyright © 2011-2022 走看看