C#WinForm上传文件的方案

1、501 为实现错误
解决方法: 先把IISWEB服务扩展中的WebDev打开。然后,IIS站点添加MIME  txt类型 常见的MIME类型如下:
超文本标记语言文本 .html,.html text/html 
普通文本 .txt text/plain 
RTF文本 .rtf application/rtf 
GIF图形 .gif image/gif 
JPEG图形 .ipeg,.jpg image/jpeg 
au声音文件 .au audio/basic 
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi 
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio 
MPEG文件 .mpg,.mpeg video/mpeg 
AVI文件 .avi video/x-msvideo 
GZIP文件 .gz application/x-gzip 
TAR文件 .tar application/x-tar 
其次,设置目标文件夹的可写性

[csharp] view plain copy
print ?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Net;  
  5. using System.IO;  
  6.   
  7. namespace Common  
  8. {  
  9.     /// <summary>  
  10.     /// winform形式的文件传输类  
  11.     /// </summary>  
  12.     public class WinFileTransporter  
  13.     {  
  14.         /// <summary>  
  15.         /// WebClient上传文件至服务器,默认不自动改名  
  16.         /// </summary>  
  17.         /// <param name="fileNamePath">文件名,全路径格式</param>  
  18.         /// <param name="uriString">服务器文件夹路径</param>  
  19.         public void UpLoadFile(string fileNamePath, string uriString)  
  20.         {  
  21.             UpLoadFile(fileNamePath, uriString, false);  
  22.         }  
  23.         /// <summary>  
  24.         /// WebClient上传文件至服务器  
  25.         /// </summary>  
  26.         /// <param name="fileNamePath">文件名,全路径格式</param>  
  27.         /// <param name="uriString">服务器文件夹路径</param>  
  28.         /// <param name="IsAutoRename">是否自动按照时间重命名</param>  
  29.         public void UpLoadFile(string fileNamePath, string uriString, bool IsAutoRename)  
  30.         {  
  31.             string fileName = fileNamePath.Substring(fileNamePath.LastIndexOf("\\") + 1);  
  32.             string NewFileName = fileName;  
  33.             if (IsAutoRename)  
  34.             {  
  35.                 NewFileName = DateTime.Now.ToString("yyMMddhhmmss") + DateTime.Now.Millisecond.ToString() + fileNamePath.Substring(fileNamePath.LastIndexOf("."));  
  36.             }  
  37.             string fileNameExt = fileName.Substring(fileName.LastIndexOf(".") + 1);  
  38.             if (uriString.EndsWith("/") == false) uriString = uriString + "/";  
  39.   
  40.             uriString = uriString + NewFileName;  
  41.             Utility.LogWriter log = new Utility.LogWriter();  
  42.             //log.AddLog(uriString, "Log");  
  43.             //log.AddLog(fileNamePath, "Log");  
  44.             /**/  
  45.             /// 创建WebClient实例  
  46.             WebClient myWebClient = new WebClient();  
  47.             myWebClient.Credentials = CredentialCache.DefaultCredentials;  
  48.             // 要上传的文件  
  49.             FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);  
  50.             //FileStream fs = OpenFile();  
  51.             BinaryReader r = new BinaryReader(fs);  
  52.             byte[] postArray = r.ReadBytes((int)fs.Length);  
  53.             Stream postStream = myWebClient.OpenWrite(uriString, "PUT");  
  54.             try  
  55.             {  
  56.                 //使用UploadFile方法可以用下面的格式  
  57.                 //myWebClient.UploadFile(uriString,"PUT",fileNamePath);  
  58.   
  59.                 if (postStream.CanWrite)  
  60.                 {  
  61.                     postStream.Write(postArray, 0, postArray.Length);  
  62.                     postStream.Close();  
  63.                     fs.Dispose();  
  64.                     log.AddLog("上传日志文件成功!""Log");  
  65.                 }  
  66.                 else  
  67.                 {  
  68.                     postStream.Close();  
  69.                     fs.Dispose();  
  70.                     log.AddLog("上传日志文件失败,文件不可写!""Log");  
  71.                 }  
  72.   
  73.             }  
  74.             catch (Exception err)  
  75.             {  
  76.                 postStream.Close();  
  77.                 fs.Dispose();  
  78.                 //Utility.LogWriter log = new Utility.LogWriter();  
  79.                 log.AddLog(err, "上传日志文件异常!""Log");  
  80.                 throw err;  
  81.             }  
  82.             finally  
  83.             {  
  84.                 postStream.Close();  
  85.                 fs.Dispose();  
  86.             }  
  87.         }  
  88.         /**/  
  89.         /// <summary>  
  90.         /// 下载服务器文件至客户端  
  91.         /// </summary>  
  92.         /// <param name="URL">被下载的文件地址,绝对路径</param>  
  93.         /// <param name="Dir">另存放的目录</param>  
  94.         public void Download(string URL, string Dir)  
  95.         {  
  96.             WebClient client = new WebClient();  
  97.             string fileName = URL.Substring(URL.LastIndexOf("\\") + 1);  //被下载的文件名  
  98.   
  99.             string Path = Dir + fileName;   //另存为的绝对路径+文件名  
  100.             Utility.LogWriter log = new Utility.LogWriter();  
  101.             try  
  102.             {  
  103.                 WebRequest myre = WebRequest.Create(URL);  
  104.             }  
  105.             catch (Exception err)  
  106.             {  
  107.                 //MessageBox.Show(exp.Message,"Error");   
  108.                 log.AddLog(err, "下载日志文件异常!""Log");  
  109.             }  
  110.             try  
  111.             {  
  112.                 client.DownloadFile(URL, fileName);  
  113.                 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);  
  114.                 BinaryReader r = new BinaryReader(fs);  
  115.                 byte[] mbyte = r.ReadBytes((int)fs.Length);  
  116.   
  117.                 FileStream fstr = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.Write);  
  118.   
  119.                 fstr.Write(mbyte, 0, (int)fs.Length);  
  120.                 fstr.Close();  
  121.             }  
  122.             catch (Exception err)  
  123.             {  
  124.                 //MessageBox.Show(exp.Message,"Error");  
  125.                 log.AddLog(err, "下载日志文件异常!""Log");  
  126.             }  
  127.         }  
  128.     }  
  129. }  
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace Common
{
    /// <summary>
    /// winform形式的文件传输类
    /// </summary>
    public class WinFileTransporter
    {
        /// <summary>
        /// WebClient上传文件至服务器,默认不自动改名
        /// </summary>
        /// <param name="fileNamePath">文件名,全路径格式</param>
        /// <param name="uriString">服务器文件夹路径</param>
        public void UpLoadFile(string fileNamePath, string uriString)
        {
            UpLoadFile(fileNamePath, uriString, false);
        }
        /// <summary>
        /// WebClient上传文件至服务器
        /// </summary>
        /// <param name="fileNamePath">文件名,全路径格式</param>
        /// <param name="uriString">服务器文件夹路径</param>
        /// <param name="IsAutoRename">是否自动按照时间重命名</param>
        public void UpLoadFile(string fileNamePath, string uriString, bool IsAutoRename)
        {
            string fileName = fileNamePath.Substring(fileNamePath.LastIndexOf("\\") + 1);
            string NewFileName = fileName;
            if (IsAutoRename)
            {
                NewFileName = DateTime.Now.ToString("yyMMddhhmmss") + DateTime.Now.Millisecond.ToString() + fileNamePath.Substring(fileNamePath.LastIndexOf("."));
            }
            string fileNameExt = fileName.Substring(fileName.LastIndexOf(".") + 1);
            if (uriString.EndsWith("/") == false) uriString = uriString + "/";

            uriString = uriString + NewFileName;
            Utility.LogWriter log = new Utility.LogWriter();
            //log.AddLog(uriString, "Log");
            //log.AddLog(fileNamePath, "Log");
            /**/
            /// 创建WebClient实例
            WebClient myWebClient = new WebClient();
            myWebClient.Credentials = CredentialCache.DefaultCredentials;
            // 要上传的文件
            FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
            //FileStream fs = OpenFile();
            BinaryReader r = new BinaryReader(fs);
            byte[] postArray = r.ReadBytes((int)fs.Length);
            Stream postStream = myWebClient.OpenWrite(uriString, "PUT");
            try
            {
                //使用UploadFile方法可以用下面的格式
                //myWebClient.UploadFile(uriString,"PUT",fileNamePath);

                if (postStream.CanWrite)
                {
                    postStream.Write(postArray, 0, postArray.Length);
                    postStream.Close();
                    fs.Dispose();
                    log.AddLog("上传日志文件成功!", "Log");
                }
                else
                {
                    postStream.Close();
                    fs.Dispose();
                    log.AddLog("上传日志文件失败,文件不可写!", "Log");
                }

            }
            catch (Exception err)
            {
                postStream.Close();
                fs.Dispose();
                //Utility.LogWriter log = new Utility.LogWriter();
                log.AddLog(err, "上传日志文件异常!", "Log");
                throw err;
            }
            finally
            {
                postStream.Close();
                fs.Dispose();
            }
        }
        /**/
        /// <summary>
        /// 下载服务器文件至客户端
        /// </summary>
        /// <param name="URL">被下载的文件地址,绝对路径</param>
        /// <param name="Dir">另存放的目录</param>
        public void Download(string URL, string Dir)
        {
            WebClient client = new WebClient();
            string fileName = URL.Substring(URL.LastIndexOf("\\") + 1);  //被下载的文件名

            string Path = Dir + fileName;   //另存为的绝对路径+文件名
            Utility.LogWriter log = new Utility.LogWriter();
            try
            {
                WebRequest myre = WebRequest.Create(URL);
            }
            catch (Exception err)
            {
                //MessageBox.Show(exp.Message,"Error"); 
                log.AddLog(err, "下载日志文件异常!", "Log");
            }
            try
            {
                client.DownloadFile(URL, fileName);
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader r = new BinaryReader(fs);
                byte[] mbyte = r.ReadBytes((int)fs.Length);

                FileStream fstr = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.Write);

                fstr.Write(mbyte, 0, (int)fs.Length);
                fstr.Close();
            }
            catch (Exception err)
            {
                //MessageBox.Show(exp.Message,"Error");
                log.AddLog(err, "下载日志文件异常!", "Log");
            }
        }
    }
}

2、通过在WinForm中用HTTP协议上传文件

些人说要向服务器端上传文件,用FTP协议不是很简单吗?效率又高,为什么还要使用HTTP协议那么麻烦呢?这里面有几个原因:

(1)FTP服务器的部署相对麻烦,还要设置权限,权限设置不对,还会惹来一系列的安全问题。

(2)如果双方都还有防火墙,又不想开发FTP相关的一些端口时,HTTP就会大派用场,就像WEB Services能穿透防火墙一样。

(3)其他的...,还在想呢...

但是使用HTTP也有他的一些问题,例如不能断点续传,大文件上传很难,速度很慢,所以HTTP协议上传的文件大小不应该太大。

说了这么多,原归正传,一般来说,在Winform里通过HTTP上传文件有几种可选的方法:

(1)前面提到的Web Services,就是一种很好的方法,通过编写一个WebMethod,包含有 byte[] 类型的参数,然后调用Web Services的方法,文件内容就会以Base64编码传到服务器上,然后重新保存即可。

[csharp] view plain copy
print ?
  1. [WebMethod]  
  2. public void UploadFile(byte[] content,string filename){  
  3.            Stream sw = new StreamWriter(...);  
  4.            sw.Close();  
  5. }  
[WebMethod]
public void UploadFile(byte[] content,string filename){
           Stream sw = new StreamWriter(...);
           sw.Close();
}

当然,这种通过Base64编码的方法效率比较低,那么可以采用WSE,支持附件,并以2进制形式传送,效率会更高。
(2)除了通过WebService,另外一种更简单的方法就是通过WebClient或者HttpWebRequest来模拟HTTP的POST动作来实现。这时候首先需要编写一个asp.net web form来响应上传,代码如下:

  1. <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="UploadFileWeb.WebForm1" %>  
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >  
  3. <html>  
  4.  <head>  
  5.   <title>WebForm1</title>  
  6.   <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">  
  7.   <meta name="CODE_LANGUAGE" Content="C#">  
  8.   <meta name="vs_defaultClientScript" content="JavaScript">  
  9.   <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">  
  10.  </head>  
  11.  <body>  
  12.   <form id="Form1" method="post" runat="server">  
  13.   </form>  
  14.  </body>  
  15. </html>  
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="UploadFileWeb.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
 <head>
  <title>WebForm1</title>
  <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
  <meta name="CODE_LANGUAGE" Content="C#">
  <meta name="vs_defaultClientScript" content="JavaScript">
  <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
 </head>
 <body>
  <form id="Form1" method="post" runat="server">
  </form>
 </body>
</html>
[csharp] view plain copy
print ?
  1. using System;  
  2. using System.Collections;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Web;  
  7. using System.Web.SessionState;  
  8. using System.Web.UI;  
  9. using System.Web.UI.WebControls;  
  10. using System.Web.UI.HtmlControls;  
  11.   
  12. namespace UploadFileWeb  
  13. {  
  14.  /// <summary>  
  15.  /// WebForm1 的摘要说明。  
  16.  /// </summary>  
  17.  public class WebForm1 : System.Web.UI.Page  
  18.  {  
  19.   private void Page_Load(object sender, System.EventArgs e)  
  20.   {  
  21.    // 在此处放置用户代码以初始化页面  
  22.    foreachstring f in Request.Files.AllKeys)  
  23.    {  
  24.     HttpPostedFile file = Request.Files[f];  
  25.     file.SaveAs(@"D:\Temp\" + file.FileName);  
  26.    }  
  27.    if( Request.Params["testKey"] != null )  
  28.    {  
  29.     Response.Write(Request.Params["testKey"]);  
  30.    }  
  31.   }  
  32.  
  33.   #region Web 窗体设计器生成的代码  
  34.   override protected void OnInit(EventArgs e)  
  35.   {  
  36.    //  
  37.    // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。  
  38.    //  
  39.    InitializeComponent();  
  40.    base.OnInit(e);  
  41.   }  
  42.     
  43.   /// <summary>  
  44.   /// 设计器支持所需的方法 - 不要使用代码编辑器修改  
  45.   /// 此方法的内容。  
  46.   /// </summary>  
  47.   private void InitializeComponent()  
  48.   {      
  49.    this.Load += new System.EventHandler(this.Page_Load);  
  50.   }  
  51.   #endregion  
  52.  }  
  53. }  
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace UploadFileWeb
{
 /// <summary>
 /// WebForm1 的摘要说明。
 /// </summary>
 public class WebForm1 : System.Web.UI.Page
 {
  private void Page_Load(object sender, System.EventArgs e)
  {
   // 在此处放置用户代码以初始化页面
   foreach( string f in Request.Files.AllKeys)
   {
    HttpPostedFile file = Request.Files[f];
    file.SaveAs(@"D:\Temp\" + file.FileName);
   }
   if( Request.Params["testKey"] != null )
   {
    Response.Write(Request.Params["testKey"]);
   }
  }

  #region Web 窗体设计器生成的代码
  override protected void OnInit(EventArgs e)
  {
   //
   // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
   //
   InitializeComponent();
   base.OnInit(e);
  }
  
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {    
   this.Load += new System.EventHandler(this.Page_Load);
  }
  #endregion
 }
}

其实这个页面跟我们平常写的asp.net上传文件代码是一样的,在Web 页的Request对象中包含有Files这个对象,里面就包含了通过POST方式上传的所有文件的信息,这时所需要做的就是调用 Request.Files[i].SaveAs方法。

但是怎么让才能在WinForm里面模拟想Web Form POST 数据呢?System.Net命名空间里面提供了两个非常有用的类,一个是WebClient,另外一个是HttpWebRequest类。如果我们不需要通过代理服务器来上传文件,那么非常简单,只需要简单的调用WebClient.UploadFile方法就能实现上传文件:

[csharp] view plain copy
print ?
  1. private void button1_Click(object sender, System.EventArgs e)  
  2.   {  
  3.    WebClient myWebClient = new WebClient();  
  4.      
  5.    myWebClient.UploadFile("http://localhost/UploadFileWeb/WebForm1.aspx","POST",@"D:\Temp\Java\JavaStart\JavaStart2.exe");  
  6.        }  
private void button1_Click(object sender, System.EventArgs e)
  {
   WebClient myWebClient = new WebClient();
   
   myWebClient.UploadFile("http://localhost/UploadFileWeb/WebForm1.aspx","POST",@"D:\Temp\Java\JavaStart\JavaStart2.exe");
       }

      但是如果要通过代理服务器上传又怎么办呢?那就需要使用到HttpWebRequest,但是该类没有Upload方法,但是幸运的是我们通过Reflector反编译了WebClient.UploadFile方法后,我们发现其内部也是通过WebRequest来实现的,代码如下:

[csharp] view plain copy
print ?
  1. public byte[] UploadFile(string address, string method, string fileName)  
  2. {  
  3.       string text1;  
  4.       string text2;  
  5.       WebRequest request1;  
  6.       string text3;  
  7.       byte[] buffer1;  
  8.       byte[] buffer2;  
  9.       long num1;  
  10.       byte[] buffer3;  
  11.       int num2;  
  12.       WebResponse response1;  
  13.       byte[] buffer4;  
  14.       DateTime time1;  
  15.       long num3;  
  16.       string[] textArray1;  
  17.       FileStream stream1 = null;  
  18.       try  
  19.       {  
  20.             fileName = Path.GetFullPath(fileName);  
  21.             time1 = DateTime.Now;  
  22.             num3 = time1.Ticks;  
  23.             text1 = "---------------------" + num3.ToString("x");  
  24.             if (this.m_headers == null)  
  25.             {  
  26.                   this.m_headers = new WebHeaderCollection();  
  27.             }  
  28.             text2 = this.m_headers["Content-Type"];  
  29.             if (text2 != null)  
  30.             {  
  31.                   if (text2.ToLower(CultureInfo.InvariantCulture).StartsWith("multipart/"))  
  32.                   {  
  33.                         throw new WebException(SR.GetString("net_webclient_Multipart"));  
  34.                   }  
  35.             }  
  36.             else  
  37.             {  
  38.                   text2 = "application/octet-stream";  
  39.             }  
  40.             this.m_headers["Content-Type"] = "multipart/form-data; boundary=" + text1;  
  41.             this.m_responseHeaders = null;  
  42.             stream1 = new FileStream(fileName, FileMode.Open, FileAccess.Read);  
  43.             request1 = WebRequest.Create(this.GetUri(address));  
  44.             request1.Credentials = this.Credentials;  
  45.             this.CopyHeadersTo(request1);  
  46.             request1.Method = method;  
  47.             textArray1 = new string[7];  
  48.             textArray1[0] = "--";  
  49.             textArray1[1] = text1;  
  50.             textArray1[2] = "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"";  
  51.             textArray1[3] = Path.GetFileName(fileName);  
  52.             textArray1[4] = "\"\r\nContent-Type: ";  
  53.             textArray1[5] = text2;  
  54.             textArray1[6] = "\r\n\r\n";  
  55.             text3 = string.Concat(textArray1);  
  56.             buffer1 = Encoding.UTF8.GetBytes(text3);  
  57.             buffer2 = Encoding.ASCII.GetBytes("\r\n--" + text1 + "\r\n");  
  58.             num1 = 9223372036854775807;  
  59.             try  
  60.             {  
  61.                   num1 = stream1.Length;  
  62.                   request1.ContentLength = ((num1 + ((long) buffer1.Length)) + ((long) buffer2.Length));  
  63.             }  
  64.             catch  
  65.             {  
  66.             }  
  67.             buffer3 = new byte[Math.Min(((int) 8192), ((int) num1))];  
  68.             using (Stream stream2 = request1.GetRequestStream())  
  69.             {  
  70.                   stream2.Write(buffer1, 0, buffer1.Length);  
  71.                   do  
  72.                   {  
  73.                         num2 = stream1.Read(buffer3, 0, buffer3.Length);  
  74.                         if (num2 != 0)  
  75.                         {  
  76.                               stream2.Write(buffer3, 0, num2);  
  77.                         }  
  78.                   }  
  79.                   while ((num2 != 0));  
  80.                   stream2.Write(buffer2, 0, buffer2.Length);  
  81.             }  
  82.             stream1.Close();  
  83.             stream1 = null;  
  84.             response1 = request1.GetResponse();  
  85.             this.m_responseHeaders = response1.Headers;  
  86.             return this.ResponseAsBytes(response1);  
  87.       }  
  88.       catch (Exception exception1)  
  89.       {  
  90.             if (stream1 != null)  
  91.             {  
  92.                   stream1.Close();  
  93.                   stream1 = null;  
  94.             }  
  95.             if ((exception1 is WebException) || (exception1 is SecurityException))  
  96.             {  
  97.                   throw;  
  98.             }  
  99.             throw new WebException(SR.GetString("net_webclient"), exception1);  
  100.       }  
  101.       return buffer4;  
  102. }  
public byte[] UploadFile(string address, string method, string fileName)
{
      string text1;
      string text2;
      WebRequest request1;
      string text3;
      byte[] buffer1;
      byte[] buffer2;
      long num1;
      byte[] buffer3;
      int num2;
      WebResponse response1;
      byte[] buffer4;
      DateTime time1;
      long num3;
      string[] textArray1;
      FileStream stream1 = null;
      try
      {
            fileName = Path.GetFullPath(fileName);
            time1 = DateTime.Now;
            num3 = time1.Ticks;
            text1 = "---------------------" + num3.ToString("x");
            if (this.m_headers == null)
            {
                  this.m_headers = new WebHeaderCollection();
            }
            text2 = this.m_headers["Content-Type"];
            if (text2 != null)
            {
                  if (text2.ToLower(CultureInfo.InvariantCulture).StartsWith("multipart/"))
                  {
                        throw new WebException(SR.GetString("net_webclient_Multipart"));
                  }
            }
            else
            {
                  text2 = "application/octet-stream";
            }
            this.m_headers["Content-Type"] = "multipart/form-data; boundary=" + text1;
            this.m_responseHeaders = null;
            stream1 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            request1 = WebRequest.Create(this.GetUri(address));
            request1.Credentials = this.Credentials;
            this.CopyHeadersTo(request1);
            request1.Method = method;
            textArray1 = new string[7];
            textArray1[0] = "--";
            textArray1[1] = text1;
            textArray1[2] = "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"";
            textArray1[3] = Path.GetFileName(fileName);
            textArray1[4] = "\"\r\nContent-Type: ";
            textArray1[5] = text2;
            textArray1[6] = "\r\n\r\n";
            text3 = string.Concat(textArray1);
            buffer1 = Encoding.UTF8.GetBytes(text3);
            buffer2 = Encoding.ASCII.GetBytes("\r\n--" + text1 + "\r\n");
            num1 = 9223372036854775807;
            try
            {
                  num1 = stream1.Length;
                  request1.ContentLength = ((num1 + ((long) buffer1.Length)) + ((long) buffer2.Length));
            }
            catch
            {
            }
            buffer3 = new byte[Math.Min(((int) 8192), ((int) num1))];
            using (Stream stream2 = request1.GetRequestStream())
            {
                  stream2.Write(buffer1, 0, buffer1.Length);
                  do
                  {
                        num2 = stream1.Read(buffer3, 0, buffer3.Length);
                        if (num2 != 0)
                        {
                              stream2.Write(buffer3, 0, num2);
                        }
                  }
                  while ((num2 != 0));
                  stream2.Write(buffer2, 0, buffer2.Length);
            }
            stream1.Close();
            stream1 = null;
            response1 = request1.GetResponse();
            this.m_responseHeaders = response1.Headers;
            return this.ResponseAsBytes(response1);
      }
      catch (Exception exception1)
      {
            if (stream1 != null)
            {
                  stream1.Close();
                  stream1 = null;
            }
            if ((exception1 is WebException) || (exception1 is SecurityException))
            {
                  throw;
            }
            throw new WebException(SR.GetString("net_webclient"), exception1);
      }
      return buffer4;
}

在这段代码里面其实最关键的就是如何模拟POST请求,通过分析代码和监视HTTP,我们可以发现模拟的POST格式如下:

-----------------------8c64f47716481f0  //时间戳

Content-Disposition: form-data; name="file"; filename="a.txt"  //文件名

Content-Type: application/octet-stream

//文件的内容

-----------------------8c64f47716481f0

这时候,只需编码来模拟这么一组数据就行,以下就是代码(声明一下,借用了别人的代码)

[csharp] view plain copy
print ?
  1. public class wwHttp  
  2.  {  
  3.   
  4.   /// <summary>  
  5.   /// Fires progress events when using GetUrlEvents() to retrieve a URL.  
  6.   /// </summary>  
  7.   public event OnReceiveDataHandler OnReceiveData;  
  8.   
  9.   /// <summary>  
  10.   /// Determines how data is POSTed when cPostBuffer is set.  
  11.   /// 1 - UrlEncoded  
  12.   /// 2 - Multi-Part form vars  
  13.   /// 4 - XML (raw buffer content type: text/xml)  
  14.   /// </summary>  
  15.   public int PostMode   
  16.   {  
  17.    get { return this.nPostMode; }  
  18.    set { this.nPostMode = value; }  
  19.   }  
  20.   
  21.   /// <summary>  
  22.   ///  User name used for Authentication.   
  23.   ///  To use the currently logged in user when accessing an NTLM resource you can use "AUTOLOGIN".  
  24.   /// </summary>  
  25.   public string Username   
  26.   {  
  27.    get { return this.cUsername; }  
  28.    set { cUsername = value; }  
  29.   }  
  30.   
  31.   /// <summary>  
  32.   /// Password for Authentication.  
  33.   /// </summary>  
  34.   public string Password   
  35.   {  
  36.    get {return this.cPassword;}  
  37.    set {this.cPassword = value;}  
  38.   }  
  39.   
  40.   /// <summary>  
  41.   /// Address of the Proxy Server to be used.  
  42.   /// Use optional DEFAULTPROXY value to specify that you want to IE's Proxy Settings  
  43.   /// </summary>  
  44.   public string ProxyAddress    
  45.   {  
  46.    get {return this.cProxyAddress;}  
  47.    set {this.cProxyAddress = value;}  
  48.   }  
  49.   
  50.   /// <summary>  
  51.   /// Semicolon separated Address list of the servers the proxy is not used for.  
  52.   /// </summary>  
  53.   public string ProxyBypass   
  54.   {  
  55.    get {return this.cProxyBypass;}  
  56.    set {this.cProxyBypass = value;}  
  57.   }  
  58.   
  59.   /// <summary>  
  60.   /// Username for a password validating Proxy. Only used if the proxy info is set.  
  61.   /// </summary>  
  62.   public string ProxyUsername   
  63.   {  
  64.    get {return this.cProxyUsername;}  
  65.    set {this.cProxyUsername = value;}  
  66.   }  
  67.   /// <summary>  
  68.   /// Password for a password validating Proxy. Only used if the proxy info is set.  
  69.   /// </summary>  
  70.   public string ProxyPassword   
  71.   {  
  72.    get {return this.cProxyPassword;}  
  73.    set {this.cProxyPassword = value;}  
  74.   }  
  75.   
  76.   /// <summary>  
  77.   /// Timeout for the Web request in seconds. Times out on connection, read and send operations.  
  78.   /// Default is 30 seconds.  
  79.   /// </summary>  
  80.   public int Timeout   
  81.   {  
  82.    get {return this.nConnectTimeout; }  
  83.    set {this.nConnectTimeout = value; }  
  84.   }  
  85.   
  86.   /// <summary>  
  87.   /// Error Message if the Error Flag is set or an error value is returned from a method.  
  88.   /// </summary>  
  89.   public string ErrorMsg   
  90.   {  
  91.    get { return this.cErrorMsg; }   
  92.    set { this.cErrorMsg = value; }  
  93.   }  
  94.     
  95.   /// <summary>  
  96.   /// Error flag if an error occurred.  
  97.   /// </summary>  
  98.   public bool Error  
  99.   {  
  100.    get { return this.bError; }   
  101.    set { this.bError = value; }  
  102.   }  
  103.   
  104.   /// <summary>  
  105.   /// Determines whether errors cause exceptions to be thrown. By default errors   
  106.   /// are handled in the class and the Error property is set for error conditions.  
  107.   /// (not implemented at this time).  
  108.   /// </summary>  
  109.   public bool ThrowExceptions   
  110.   {  
  111.    get { return bThrowExceptions; }  
  112.    set { this.bThrowExceptions = value;}  
  113.   }  
  114.   
  115.   /// <summary>  
  116.   /// If set to a non-zero value will automatically track cookies. The number assigned is the cookie count.  
  117.   /// </summary>  
  118.   public bool HandleCookies  
  119.   {  
  120.    get { return this.bHandleCookies; }  
  121.    set { this.bHandleCookies = value; }  
  122.   }  
  123.   public CookieCollection Cookies {  
  124.    get { return this.oCookies; }  
  125.    set { this.Cookies = value; }  
  126.   }  
  127.   public HttpWebResponse WebResponse  {  
  128.    get { return this.oWebResponse;}  
  129.    set { this.oWebResponse = value; }  
  130.   }  
  131.   public HttpWebRequest WebRequest  {  
  132.    get { return this.oWebRequest; }  
  133.    set { this.oWebRequest = value; }  
  134.   }  
  135.   
  136.   // *** member properties  
  137.   //string cPostBuffer = "";  
  138.   MemoryStream oPostStream;  
  139.   BinaryWriter oPostData;  
  140.   
  141.   int nPostMode = 1;  
  142.   
  143.   int nConnectTimeout = 30;  
  144.   string cUserAgent = "West Wind HTTP .NET";  
  145.   
  146.   string cUsername = "";  
  147.   string cPassword = "";  
  148.   
  149.   string cProxyAddress = "";  
  150.   string cProxyBypass = "";  
  151.   string cProxyUsername = "";  
  152.   string cProxyPassword = "";  
  153.   
  154.   bool bThrowExceptions = false;  
  155.   bool bHandleCookies = false;  
  156.     
  157.   string cErrorMsg = "";  
  158.   bool bError = false;  
  159.     
  160.   HttpWebResponse oWebResponse;  
  161.   HttpWebRequest oWebRequest;  
  162.   CookieCollection oCookies;  
  163.   
  164.   string cMultiPartBoundary = "-----------------------------7cf2a327f01ae";  
  165.   
  166.   public void wwHTTP()  
  167.   {  
  168.    //  
  169.    // TODO: Add constructor logic here  
  170.    //  
  171.   
  172.   }  
  173.   
  174.   /// <summary>  
  175.   /// Adds POST form variables to the request buffer.  
  176.   /// HttpPostMode determines how parms are handled.  
  177.   /// 1 - UrlEncoded Form Variables. Uses key and value pairs (ie. "Name","Rick") to create URLEncoded content  
  178.   /// 2 - Multi-Part Forms - not supported  
  179.   /// 4 - XML block - Post a single XML block. Pass in as Key (1st Parm)  
  180.   /// other - raw content buffer. Just assign to Key.  
  181.   /// </summary>  
  182.   /// <param name="Key">Key value or raw buffer depending on post type</param>  
  183.   /// <param name="Value">Value to store. Used only in key/value pair modes</param>  
  184.   public void AddPostKey(string Key, byte[] Value)  
  185.   {  
  186.      
  187.    if (this.oPostData == null)   
  188.    {  
  189.     this.oPostStream = new MemoryStream();  
  190.     this.oPostData = new BinaryWriter(this.oPostStream);  
  191.    }  
  192.      
  193.    if (Key == "RESET")   
  194.    {  
  195.     this.oPostStream = new MemoryStream();  
  196.     this.oPostData = new BinaryWriter(this.oPostStream);  
  197.    }  
  198.   
  199.    switch(this.nPostMode)  
  200.    {  
  201.     case 1:  
  202.      this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(  
  203.           Key + "=" + System.Web.HttpUtility.UrlEncode(Value) + "&"));  
  204.      break;  
  205.     case 2:  
  206.      this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(  
  207.       "--" + this.cMultiPartBoundary + "\r\n" +   
  208.       "Content-Disposition: form-data; name=\"" +Key+"\"\r\n\r\n") );  
  209.        
  210.      this.oPostData.Write( Value );  
  211.   
  212.      this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n") );  
  213.      break;  
  214.     default:  
  215.      this.oPostData.Write( Value );  
  216.      break;  
  217.    }  
  218.   }  
  219.   
  220.   public void AddPostKey(string Key, string Value)  
  221.   {  
  222.    this.AddPostKey(Key,Encoding.GetEncoding(1252).GetBytes(Value));  
  223.   }  
  224.   
  225.   /// <summary>  
  226.   /// Adds a fully self contained POST buffer to the request.  
  227.   /// Works for XML or previously encoded content.  
  228.   /// </summary>  
  229.   /// <param name="PostBuffer"></param>  
  230.   public void AddPostKey(string FullPostBuffer)   
  231.   {  
  232.    this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(FullPostBuffer) );  
  233.   }  
  234.   
  235.   public bool AddPostFile(string Key,string FileName)   
  236.   {  
  237.    byte[] lcFile;   
  238.   
  239.    if (this.nPostMode != 2) {  
  240.     this.cErrorMsg = "File upload allowed only with Multi-part forms";  
  241.     this.bError = true;  
  242.     return false;  
  243.    }  
  244.   
  245.    try   
  246.    {     
  247.     FileStream loFile = new FileStream(FileName,System.IO.FileMode.Open,System.IO.FileAccess.Read);  
  248.   
  249.     lcFile = new byte[loFile.Length];  
  250.     loFile.Read(lcFile,0,(int) loFile.Length);  
  251.     loFile.Close();  
  252.    }  
  253.    catch(Exception e)   
  254.    {  
  255.     this.cErrorMsg = e.Message;  
  256.     this.bError = true;  
  257.     return false;  
  258.    }  
  259.   
  260.    this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(  
  261.      "--" + this.cMultiPartBoundary + "\r\n"  +   
  262.      "Content-Disposition: form-data; name=\"" + Key + "\" filename=\"" +   
  263.      new FileInfo(FileName).Name + "\"\r\n\r\n") );  
  264.   
  265.    this.oPostData.Write( lcFile );  
  266.   
  267.    this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n")) ;  
  268.   
  269.    return true;  
  270.   }  
  271.   
  272.   
  273.   /// <summary>  
  274.   /// Return a the result from an HTTP Url into a StreamReader.  
  275.   /// Client code should call Close() on the returned object when done reading.  
  276.   /// </summary>  
  277.   /// <param name="Url">Url to retrieve.</param>  
  278.   /// <param name="WebRequest">An HttpWebRequest object that can be passed in with properties preset.</param>  
  279.   /// <returns></returns>  
  280.   protected StreamReader GetUrlStream(string Url,HttpWebRequest Request)  
  281.   {  
  282.    try   
  283.    {  
  284.     this.bError = false;  
  285.     this.cErrorMsg = "";  
  286.   
  287.   
  288.     if (Request == null)   
  289.     {  
  290.      Request =  (HttpWebRequest) System.Net.WebRequest.Create(Url);  
  291.     }  
  292.       
  293.     Request.UserAgent = this.cUserAgent;  
  294.     Request.Timeout = this.nConnectTimeout * 1000;  
  295.   
  296.     // *** Save for external access  
  297.     this.oWebRequest = Request;  
  298.   
  299.     // *** Handle Security for the request  
  300.     if (this.cUsername.Length > 0)   
  301.     {  
  302.      if (this.cUsername=="AUTOLOGIN")  
  303.       Request.Credentials = CredentialCache.DefaultCredentials;  
  304.      else  
  305.       Request.Credentials = new NetworkCredential(this.cUsername,this.cPassword);  
  306.     }  
  307.   
  308.      
  309.     // *** Handle Proxy Server configuration  
  310.     if (this.cProxyAddress.Length > 0)   
  311.     {  
  312.      if (this.cProxyAddress == "DEFAULTPROXY")   
  313.      {  
  314.       Request.Proxy = new WebProxy();  
  315.       Request.Proxy = WebProxy.GetDefaultProxy();  
  316.      }  
  317.      else   
  318.      {  
  319.       WebProxy loProxy = new WebProxy(this.cProxyAddress,true);  
  320.       if (this.cProxyBypass.Length > 0)   
  321.       {  
  322.        loProxy.BypassList = this.cProxyBypass.Split(';');  
  323.       }  
  324.   
  325.       if (this.cProxyUsername.Length > 0)  
  326.        loProxy.Credentials = new NetworkCredential(this.cProxyUsername,this.cProxyPassword);  
  327.   
  328.       Request.Proxy = loProxy;  
  329.      }  
  330.     }  
  331.       
  332.     // *** Handle cookies - automatically re-assign   
  333.     if (this.bHandleCookies)   
  334.     {  
  335.      Request.CookieContainer = new CookieContainer();  
  336.      if (this.oCookies != null && this.oCookies.Count > 0)   
  337.      {  
  338.       Request.CookieContainer.Add(this.oCookies);  
  339.      }  
  340.     }  
  341.   
  342.     // *** Deal with the POST buffer if any  
  343.     if (this.oPostData != null)   
  344.     {  
  345.      Request.Method = "POST";  
  346.      switch (this.nPostMode)   
  347.      {  
  348.       case 1:  
  349.        Request.ContentType = "application/x-www-form-urlencoded";  
  350.        // strip off any trailing & which can cause problems with some   
  351.        // http servers  
  352. //       if (this.cPostBuffer.EndsWith("&"))  
  353. //        this.cPostBuffer = this.cPostBuffer.Substring(0,this.cPostBuffer.Length-1);  
  354.        break;  
  355.       case 2:  
  356.        Request.ContentType = "multipart/form-data; boundary=" + this.cMultiPartBoundary;  
  357.        this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes( "--" + this.cMultiPartBoundary + "\r\n" ) );  
  358.        break;  
  359.       case 4:  
  360.        Request.ContentType = "text/xml";  
  361.        break;  
  362.       default:  
  363.        goto case 1;  
  364.      }  
  365.        
  366.   
  367.      Stream loPostData = Request.GetRequestStream();  
  368.      //loPostData.Write(lcPostData,0,lcPostData.Length);  
  369.      this.oPostStream.WriteTo(loPostData);     
  370.        
  371.      byte[] buffer = new byte[this.oPostStream.Length];  
  372.      buffer = this.oPostStream.ToArray();  
  373.      Console.Write(Encoding.GetEncoding(1252).GetString(buffer,0,buffer.Length));  
  374.   
  375.      //*** Close the memory stream  
  376.      this.oPostStream.Close();  
  377.      this.oPostStream = null;  
  378.   
  379.        
  380.      //*** Close the Binary Writer  
  381.      this.oPostData.Close();  
  382.      this.oPostData = null;  
  383.   
  384.      //*** Close Request Stream  
  385.      loPostData.Close();  
  386.   
  387.      // *** clear the POST buffer  
  388.      //this.cPostBuffer = "";  
  389.     }  
  390.     
  391.     // *** Retrieve the response headers   
  392.     HttpWebResponse Response = (HttpWebResponse) Request.GetResponse();  
  393.   
  394.     // ** Save cookies the server sends  
  395.     if (this.bHandleCookies)    
  396.     {  
  397.      if (Response.Cookies.Count > 0)    
  398.      {  
  399.       if (this.oCookies == null)    
  400.       {  
  401.        this.oCookies = Response.Cookies;  
  402.       }  
  403.       else   
  404.       {  
  405.        // ** If we already have cookies update the list  
  406.        foreach (Cookie oRespCookie in Response.Cookies)    
  407.        {  
  408.         bool bMatch = false;  
  409.         foreach(Cookie oReqCookie in this.oCookies)    
  410.         {  
  411.          if (oReqCookie.Name == oRespCookie.Name)    
  412.          {  
  413.           oReqCookie.Value = oRespCookie.Name;  
  414.           bMatch = true;  
  415.           break//   
  416.          }  
  417.         } // for each ReqCookies  
  418.         if (!bMatch)  
  419.          this.oCookies.Add(oRespCookie);  
  420.        } // for each Response.Cookies  
  421.       }  // this.Cookies == null  
  422.      } // if Response.Cookie.Count > 0  
  423.     }  // if this.bHandleCookies = 0  
  424.   
  425.       
  426.     // *** Save the response object for external access  
  427.     this.oWebResponse = Response;  
  428.   
  429.     Encoding enc;  
  430.     try   
  431.     {  
  432.      if (Response.ContentEncoding.Length  > 0)  
  433.       enc = Encoding.GetEncoding(Response.ContentEncoding);  
  434.      else  
  435.       enc = Encoding.GetEncoding(1252);  
  436.     }  
  437.     catch  
  438.     {  
  439.      // *** Invalid encoding passed  
  440.      enc = Encoding.GetEncoding(1252);   
  441.     }  
  442.       
  443.     // *** drag to a stream  
  444.     StreamReader strResponse =   
  445.      new StreamReader(Response.GetResponseStream(),enc);   
  446.     return strResponse;  
  447.    }  
  448.    catch(Exception e)   
  449.    {  
  450.     if (this.bThrowExceptions)   
  451.      throw e;  
  452.   
  453.     this.cErrorMsg = e.Message;  
  454.     this.bError = true;  
  455.     return null;  
  456.    }  
  457.   }  
  458.   
  459.   /// <summary>  
  460.   /// Return a the result from an HTTP Url into a StreamReader.  
  461.   /// Client code should call Close() on the returned object when done reading.  
  462.   /// </summary>  
  463.   /// <param name="Url">Url to retrieve.</param>  
  464.   /// <returns></returns>  
  465.   public StreamReader GetUrlStream(string Url)  
  466.   {  
  467.    HttpWebRequest oHttpWebRequest = null;  
  468.    return this.GetUrlStream(Url,oHttpWebRequest);  
  469.   }  
  470.   
  471.   /// <summary>  
  472.   /// Return a the result from an HTTP Url into a StreamReader.  
  473.   /// Client code should call Close() on the returned object when done reading.  
  474.   /// </summary>  
  475.   /// <param name="Request">A Request object</param>  
  476.   /// <returns></returns>  
  477.   public StreamReader GetUrlStream(HttpWebRequest Request)  
  478.   {  
  479.    return this.GetUrlStream(Request.RequestUri.AbsoluteUri,Request);  
  480.   }  
  481.   
  482.   /// <summary>  
  483.   /// Return a the result from an HTTP Url into a string.  
  484.   /// </summary>  
  485.   /// <param name="Url">Url to retrieve.</param>  
  486.   /// <returns></returns>  
  487.   public string GetUrl(string Url)  
  488.   {  
  489.    StreamReader oHttpResponse = this.GetUrlStream(Url);  
  490.    if (oHttpResponse == null)  
  491.     return "";  
  492.   
  493.    string lcResult = oHttpResponse.ReadToEnd();  
  494.    oHttpResponse.Close();  
  495.   
  496.    return lcResult;  
  497.   }  
  498.   
  499.   /// <summary>  
  500.   /// Return a the result from an HTTP Url into a string.  
  501.   /// </summary>  
  502.   /// <param name="Url">Url to retrieve.</param>  
  503.   /// <returns></returns>  
  504.   public byte[] GetUrlBytes(string Url)  
  505.   {  
  506.    StreamReader oHttpResponse = this.GetUrlStream(Url);  
  507.      
  508.    if (oHttpResponse == null)   
  509.    {  
  510.     return null;  
  511.    }  
  512.   
  513.    string lcResult = oHttpResponse.ReadToEnd();  
  514.    oHttpResponse.Close();  
  515.   
  516.    return null;  
  517.   }  
  518.   
  519.   /// <summary>  
  520.   /// Retrieves URL with events in the OnReceiveData event.  
  521.   /// </summary>  
  522.   /// <param name="Url"></param>  
  523.   /// <param name="BufferSize"></param>  
  524.   /// <returns></returns>  
  525.   public string GetUrlEvents(string Url,long BufferSize)   
  526.   {  
  527.     
  528.    StreamReader oHttpResponse = this.GetUrlStream(Url);  
  529.    if (oHttpResponse == null)  
  530.     return "";  
  531.   
  532.    long lnSize = BufferSize;  
  533.    if (this.oWebResponse.ContentLength > 0)  
  534.     lnSize = this.oWebResponse.ContentLength;  
  535.    else  
  536.     lnSize = 0;  
  537.   
  538.    Encoding enc = Encoding.GetEncoding(1252);  
  539.   
  540.    StringBuilder loWriter = new StringBuilder((int) lnSize);  
  541.         
  542.    char[] lcTemp = new char[BufferSize];  
  543.   
  544.    OnReceiveDataEventArgs oArgs = new OnReceiveDataEventArgs();  
  545.    oArgs.TotalBytes = lnSize;  
  546.   
  547.    lnSize = 1;  
  548.    int lnCount = 0;  
  549.    long lnTotalBytes = 0;  
  550.   
  551.    while (lnSize > 0)   
  552.    {  
  553.     lnSize = oHttpResponse.Read(lcTemp,0,(int) BufferSize);  
  554.     if (lnSize > 0)   
  555.     {  
  556.      loWriter.Append( lcTemp,0,(int) lnSize );  
  557.      lnCount++;  
  558.      lnTotalBytes += lnSize;  
  559.   
  560.      // *** Raise an event if hooked up  
  561.      if (this.OnReceiveData != null)   
  562.      {  
  563.       /// *** Update the event handler  
  564.       oArgs.CurrentByteCount = lnTotalBytes;  
  565.       oArgs.NumberOfReads = lnCount;  
  566.       oArgs.CurrentChunk = lcTemp;  
  567.       this.OnReceiveData(this,oArgs);  
  568.   
  569.       // *** Check for cancelled flag  
  570.       if (oArgs.Cancel)  
  571.        goto CloseDown;  
  572.      }  
  573.     }  
  574.    } // while  
  575.   
  576.   
  577.   CloseDown:  
  578.    oHttpResponse.Close();  
  579.   
  580.    // *** Send Done notification  
  581.    if (this.OnReceiveData != null && !oArgs.Cancel)   
  582.    {  
  583.     // *** Update the event handler  
  584.     oArgs.Done = true;  
  585.     this.OnReceiveData(this,oArgs);  
  586.    }  
  587.   
  588. //   return lcHtml;  
  589.    return loWriter.ToString();  
  590.   }  
  591.   
  592.   
  593.   public delegate void OnReceiveDataHandler(object sender, OnReceiveDataEventArgs e);  
  594.   public class OnReceiveDataEventArgs   
  595.   {  
  596.    public long CurrentByteCount=0;  
  597.    public long TotalBytes = 0;  
  598.    public int NumberOfReads = 0;  
  599.    public char[] CurrentChunk;  
  600.    public bool Done = false;  
  601.    public bool Cancel = false;  
  602.   }    
  603.  }  
public class wwHttp
 {

  /// <summary>
  /// Fires progress events when using GetUrlEvents() to retrieve a URL.
  /// </summary>
  public event OnReceiveDataHandler OnReceiveData;

  /// <summary>
  /// Determines how data is POSTed when cPostBuffer is set.
  /// 1 - UrlEncoded
  /// 2 - Multi-Part form vars
  /// 4 - XML (raw buffer content type: text/xml)
  /// </summary>
  public int PostMode 
  {
   get { return this.nPostMode; }
   set { this.nPostMode = value; }
  }

  /// <summary>
  ///  User name used for Authentication. 
  ///  To use the currently logged in user when accessing an NTLM resource you can use "AUTOLOGIN".
  /// </summary>
  public string Username 
  {
   get { return this.cUsername; }
   set { cUsername = value; }
  }

  /// <summary>
  /// Password for Authentication.
  /// </summary>
  public string Password 
  {
   get {return this.cPassword;}
   set {this.cPassword = value;}
  }

  /// <summary>
  /// Address of the Proxy Server to be used.
  /// Use optional DEFAULTPROXY value to specify that you want to IE's Proxy Settings
  /// </summary>
  public string ProxyAddress  
  {
   get {return this.cProxyAddress;}
   set {this.cProxyAddress = value;}
  }

  /// <summary>
  /// Semicolon separated Address list of the servers the proxy is not used for.
  /// </summary>
  public string ProxyBypass 
  {
   get {return this.cProxyBypass;}
   set {this.cProxyBypass = value;}
  }

  /// <summary>
  /// Username for a password validating Proxy. Only used if the proxy info is set.
  /// </summary>
  public string ProxyUsername 
  {
   get {return this.cProxyUsername;}
   set {this.cProxyUsername = value;}
  }
  /// <summary>
  /// Password for a password validating Proxy. Only used if the proxy info is set.
  /// </summary>
  public string ProxyPassword 
  {
   get {return this.cProxyPassword;}
   set {this.cProxyPassword = value;}
  }

  /// <summary>
  /// Timeout for the Web request in seconds. Times out on connection, read and send operations.
  /// Default is 30 seconds.
  /// </summary>
  public int Timeout 
  {
   get {return this.nConnectTimeout; }
   set {this.nConnectTimeout = value; }
  }

  /// <summary>
  /// Error Message if the Error Flag is set or an error value is returned from a method.
  /// </summary>
  public string ErrorMsg 
  {
   get { return this.cErrorMsg; } 
   set { this.cErrorMsg = value; }
  }
  
  /// <summary>
  /// Error flag if an error occurred.
  /// </summary>
  public bool Error
  {
   get { return this.bError; } 
   set { this.bError = value; }
  }

  /// <summary>
  /// Determines whether errors cause exceptions to be thrown. By default errors 
  /// are handled in the class and the Error property is set for error conditions.
  /// (not implemented at this time).
  /// </summary>
  public bool ThrowExceptions 
  {
   get { return bThrowExceptions; }
   set { this.bThrowExceptions = value;}
  }

  /// <summary>
  /// If set to a non-zero value will automatically track cookies. The number assigned is the cookie count.
  /// </summary>
  public bool HandleCookies
  {
   get { return this.bHandleCookies; }
   set { this.bHandleCookies = value; }
  }
  public CookieCollection Cookies {
   get { return this.oCookies; }
   set { this.Cookies = value; }
  }
  public HttpWebResponse WebResponse  {
   get { return this.oWebResponse;}
   set { this.oWebResponse = value; }
  }
  public HttpWebRequest WebRequest  {
   get { return this.oWebRequest; }
   set { this.oWebRequest = value; }
  }

  // *** member properties
  //string cPostBuffer = "";
  MemoryStream oPostStream;
  BinaryWriter oPostData;

  int nPostMode = 1;

  int nConnectTimeout = 30;
  string cUserAgent = "West Wind HTTP .NET";

  string cUsername = "";
  string cPassword = "";

  string cProxyAddress = "";
  string cProxyBypass = "";
  string cProxyUsername = "";
  string cProxyPassword = "";

  bool bThrowExceptions = false;
  bool bHandleCookies = false;
  
  string cErrorMsg = "";
  bool bError = false;
  
  HttpWebResponse oWebResponse;
  HttpWebRequest oWebRequest;
  CookieCollection oCookies;

  string cMultiPartBoundary = "-----------------------------7cf2a327f01ae";

  public void wwHTTP()
  {
   //
   // TODO: Add constructor logic here
   //

  }

  /// <summary>
  /// Adds POST form variables to the request buffer.
  /// HttpPostMode determines how parms are handled.
  /// 1 - UrlEncoded Form Variables. Uses key and value pairs (ie. "Name","Rick") to create URLEncoded content
  /// 2 - Multi-Part Forms - not supported
  /// 4 - XML block - Post a single XML block. Pass in as Key (1st Parm)
  /// other - raw content buffer. Just assign to Key.
  /// </summary>
  /// <param name="Key">Key value or raw buffer depending on post type</param>
  /// <param name="Value">Value to store. Used only in key/value pair modes</param>
  public void AddPostKey(string Key, byte[] Value)
  {
   
   if (this.oPostData == null) 
   {
    this.oPostStream = new MemoryStream();
    this.oPostData = new BinaryWriter(this.oPostStream);
   }
   
   if (Key == "RESET") 
   {
    this.oPostStream = new MemoryStream();
    this.oPostData = new BinaryWriter(this.oPostStream);
   }

   switch(this.nPostMode)
   {
    case 1:
     this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(
          Key + "=" + System.Web.HttpUtility.UrlEncode(Value) + "&"));
     break;
    case 2:
     this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(
      "--" + this.cMultiPartBoundary + "\r\n" + 
      "Content-Disposition: form-data; name=\"" +Key+"\"\r\n\r\n") );
     
     this.oPostData.Write( Value );

     this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n") );
     break;
    default:
     this.oPostData.Write( Value );
     break;
   }
  }

  public void AddPostKey(string Key, string Value)
  {
   this.AddPostKey(Key,Encoding.GetEncoding(1252).GetBytes(Value));
  }

  /// <summary>
  /// Adds a fully self contained POST buffer to the request.
  /// Works for XML or previously encoded content.
  /// </summary>
  /// <param name="PostBuffer"></param>
  public void AddPostKey(string FullPostBuffer) 
  {
   this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(FullPostBuffer) );
  }

  public bool AddPostFile(string Key,string FileName) 
  {
   byte[] lcFile; 

   if (this.nPostMode != 2) {
    this.cErrorMsg = "File upload allowed only with Multi-part forms";
    this.bError = true;
    return false;
   }

   try 
   {   
    FileStream loFile = new FileStream(FileName,System.IO.FileMode.Open,System.IO.FileAccess.Read);

    lcFile = new byte[loFile.Length];
    loFile.Read(lcFile,0,(int) loFile.Length);
    loFile.Close();
   }
   catch(Exception e) 
   {
    this.cErrorMsg = e.Message;
    this.bError = true;
    return false;
   }

   this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(
     "--" + this.cMultiPartBoundary + "\r\n"  + 
     "Content-Disposition: form-data; name=\"" + Key + "\" filename=\"" + 
     new FileInfo(FileName).Name + "\"\r\n\r\n") );

   this.oPostData.Write( lcFile );

   this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n")) ;

   return true;
  }


  /// <summary>
  /// Return a the result from an HTTP Url into a StreamReader.
  /// Client code should call Close() on the returned object when done reading.
  /// </summary>
  /// <param name="Url">Url to retrieve.</param>
  /// <param name="WebRequest">An HttpWebRequest object that can be passed in with properties preset.</param>
  /// <returns></returns>
  protected StreamReader GetUrlStream(string Url,HttpWebRequest Request)
  {
   try 
   {
    this.bError = false;
    this.cErrorMsg = "";


    if (Request == null) 
    {
     Request =  (HttpWebRequest) System.Net.WebRequest.Create(Url);
    }
    
    Request.UserAgent = this.cUserAgent;
    Request.Timeout = this.nConnectTimeout * 1000;

    // *** Save for external access
    this.oWebRequest = Request;

    // *** Handle Security for the request
    if (this.cUsername.Length > 0) 
    {
     if (this.cUsername=="AUTOLOGIN")
      Request.Credentials = CredentialCache.DefaultCredentials;
     else
      Request.Credentials = new NetworkCredential(this.cUsername,this.cPassword);
    }

   
    // *** Handle Proxy Server configuration
    if (this.cProxyAddress.Length > 0) 
    {
     if (this.cProxyAddress == "DEFAULTPROXY") 
     {
      Request.Proxy = new WebProxy();
      Request.Proxy = WebProxy.GetDefaultProxy();
     }
     else 
     {
      WebProxy loProxy = new WebProxy(this.cProxyAddress,true);
      if (this.cProxyBypass.Length > 0) 
      {
       loProxy.BypassList = this.cProxyBypass.Split(';');
      }

      if (this.cProxyUsername.Length > 0)
       loProxy.Credentials = new NetworkCredential(this.cProxyUsername,this.cProxyPassword);

      Request.Proxy = loProxy;
     }
    }
    
    // *** Handle cookies - automatically re-assign 
    if (this.bHandleCookies) 
    {
     Request.CookieContainer = new CookieContainer();
     if (this.oCookies != null && this.oCookies.Count > 0) 
     {
      Request.CookieContainer.Add(this.oCookies);
     }
    }

    // *** Deal with the POST buffer if any
    if (this.oPostData != null) 
    {
     Request.Method = "POST";
     switch (this.nPostMode) 
     {
      case 1:
       Request.ContentType = "application/x-www-form-urlencoded";
       // strip off any trailing & which can cause problems with some 
       // http servers
//       if (this.cPostBuffer.EndsWith("&"))
//        this.cPostBuffer = this.cPostBuffer.Substring(0,this.cPostBuffer.Length-1);
       break;
      case 2:
       Request.ContentType = "multipart/form-data; boundary=" + this.cMultiPartBoundary;
       this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes( "--" + this.cMultiPartBoundary + "\r\n" ) );
       break;
      case 4:
       Request.ContentType = "text/xml";
       break;
      default:
       goto case 1;
     }
     

     Stream loPostData = Request.GetRequestStream();
     //loPostData.Write(lcPostData,0,lcPostData.Length);
     this.oPostStream.WriteTo(loPostData);   
     
     byte[] buffer = new byte[this.oPostStream.Length];
     buffer = this.oPostStream.ToArray();
     Console.Write(Encoding.GetEncoding(1252).GetString(buffer,0,buffer.Length));

     //*** Close the memory stream
     this.oPostStream.Close();
     this.oPostStream = null;

     
     //*** Close the Binary Writer
     this.oPostData.Close();
     this.oPostData = null;

     //*** Close Request Stream
     loPostData.Close();

     // *** clear the POST buffer
     //this.cPostBuffer = "";
    }
  
    // *** Retrieve the response headers 
    HttpWebResponse Response = (HttpWebResponse) Request.GetResponse();

    // ** Save cookies the server sends
    if (this.bHandleCookies)  
    {
     if (Response.Cookies.Count > 0)  
     {
      if (this.oCookies == null)  
      {
       this.oCookies = Response.Cookies;
      }
      else 
      {
       // ** If we already have cookies update the list
       foreach (Cookie oRespCookie in Response.Cookies)  
       {
        bool bMatch = false;
        foreach(Cookie oReqCookie in this.oCookies)  
        {
         if (oReqCookie.Name == oRespCookie.Name)  
         {
          oReqCookie.Value = oRespCookie.Name;
          bMatch = true;
          break; // 
         }
        } // for each ReqCookies
        if (!bMatch)
         this.oCookies.Add(oRespCookie);
       } // for each Response.Cookies
      }  // this.Cookies == null
     } // if Response.Cookie.Count > 0
    }  // if this.bHandleCookies = 0

    
    // *** Save the response object for external access
    this.oWebResponse = Response;

    Encoding enc;
    try 
    {
     if (Response.ContentEncoding.Length  > 0)
      enc = Encoding.GetEncoding(Response.ContentEncoding);
     else
      enc = Encoding.GetEncoding(1252);
    }
    catch
    {
     // *** Invalid encoding passed
     enc = Encoding.GetEncoding(1252); 
    }
    
    // *** drag to a stream
    StreamReader strResponse = 
     new StreamReader(Response.GetResponseStream(),enc); 
    return strResponse;
   }
   catch(Exception e) 
   {
    if (this.bThrowExceptions) 
     throw e;

    this.cErrorMsg = e.Message;
    this.bError = true;
    return null;
   }
  }

  /// <summary>
  /// Return a the result from an HTTP Url into a StreamReader.
  /// Client code should call Close() on the returned object when done reading.
  /// </summary>
  /// <param name="Url">Url to retrieve.</param>
  /// <returns></returns>
  public StreamReader GetUrlStream(string Url)
  {
   HttpWebRequest oHttpWebRequest = null;
   return this.GetUrlStream(Url,oHttpWebRequest);
  }

  /// <summary>
  /// Return a the result from an HTTP Url into a StreamReader.
  /// Client code should call Close() on the returned object when done reading.
  /// </summary>
  /// <param name="Request">A Request object</param>
  /// <returns></returns>
  public StreamReader GetUrlStream(HttpWebRequest Request)
  {
   return this.GetUrlStream(Request.RequestUri.AbsoluteUri,Request);
  }

  /// <summary>
  /// Return a the result from an HTTP Url into a string.
  /// </summary>
  /// <param name="Url">Url to retrieve.</param>
  /// <returns></returns>
  public string GetUrl(string Url)
  {
   StreamReader oHttpResponse = this.GetUrlStream(Url);
   if (oHttpResponse == null)
    return "";

   string lcResult = oHttpResponse.ReadToEnd();
   oHttpResponse.Close();

   return lcResult;
  }

  /// <summary>
  /// Return a the result from an HTTP Url into a string.
  /// </summary>
  /// <param name="Url">Url to retrieve.</param>
  /// <returns></returns>
  public byte[] GetUrlBytes(string Url)
  {
   StreamReader oHttpResponse = this.GetUrlStream(Url);
   
   if (oHttpResponse == null) 
   {
    return null;
   }

   string lcResult = oHttpResponse.ReadToEnd();
   oHttpResponse.Close();

   return null;
  }

  /// <summary>
  /// Retrieves URL with events in the OnReceiveData event.
  /// </summary>
  /// <param name="Url"></param>
  /// <param name="BufferSize"></param>
  /// <returns></returns>
  public string GetUrlEvents(string Url,long BufferSize) 
  {
  
   StreamReader oHttpResponse = this.GetUrlStream(Url);
   if (oHttpResponse == null)
    return "";

   long lnSize = BufferSize;
   if (this.oWebResponse.ContentLength > 0)
    lnSize = this.oWebResponse.ContentLength;
   else
    lnSize = 0;

   Encoding enc = Encoding.GetEncoding(1252);

   StringBuilder loWriter = new StringBuilder((int) lnSize);
      
   char[] lcTemp = new char[BufferSize];

   OnReceiveDataEventArgs oArgs = new OnReceiveDataEventArgs();
   oArgs.TotalBytes = lnSize;

   lnSize = 1;
   int lnCount = 0;
   long lnTotalBytes = 0;

   while (lnSize > 0) 
   {
    lnSize = oHttpResponse.Read(lcTemp,0,(int) BufferSize);
    if (lnSize > 0) 
    {
     loWriter.Append( lcTemp,0,(int) lnSize );
     lnCount++;
     lnTotalBytes += lnSize;

     // *** Raise an event if hooked up
     if (this.OnReceiveData != null) 
     {
      /// *** Update the event handler
      oArgs.CurrentByteCount = lnTotalBytes;
      oArgs.NumberOfReads = lnCount;
      oArgs.CurrentChunk = lcTemp;
      this.OnReceiveData(this,oArgs);

      // *** Check for cancelled flag
      if (oArgs.Cancel)
       goto CloseDown;
     }
    }
   } // while


  CloseDown:
   oHttpResponse.Close();

   // *** Send Done notification
   if (this.OnReceiveData != null && !oArgs.Cancel) 
   {
    // *** Update the event handler
    oArgs.Done = true;
    this.OnReceiveData(this,oArgs);
   }

//   return lcHtml;
   return loWriter.ToString();
  }


  public delegate void OnReceiveDataHandler(object sender, OnReceiveDataEventArgs e);
  public class OnReceiveDataEventArgs 
  {
   public long CurrentByteCount=0;
   public long TotalBytes = 0;
   public int NumberOfReads = 0;
   public char[] CurrentChunk;
   public bool Done = false;
   public bool Cancel = false;
  }  
 }

在wwHttp这个类里面,不仅仅可以传送文件AddPostFile方法,还可以传送变量AddPostKey方法。

这样,如果我们要通过代理服务器传送文件,就可以编写如下的代码了:

[csharp] view plain copy
print ?
  1. wwHttp ww = new wwHttp();  
  2.    ww.ProxyAddress = "202.132.156.124";     
  3.    ww.PostMode = 2;  
  4.    ww.AddPostKey("testKey","test");  
  5.    ww.AddPostFile("myfile",@"D:\Temp\Java\JavaStart\JavaStart2.jar");    
  6.      
  7.    string shtml = ww.GetUrlEvents("http://localhost/UploadFileWeb/WebForm1.aspx",409600);  
  8.    Console.Write(shtml);  
wwHttp ww = new wwHttp();
   ww.ProxyAddress = "202.132.156.124";   
   ww.PostMode = 2;
   ww.AddPostKey("testKey","test");
   ww.AddPostFile("myfile",@"D:\Temp\Java\JavaStart\JavaStart2.jar");  
   
   string shtml = ww.GetUrlEvents("http://localhost/UploadFileWeb/WebForm1.aspx",409600);
   Console.Write(shtml);

小结:

(1)通过Web Services传文件。

(2)如果不需要使用代理,使用WebClient类

(3)如果需要使用代理,使用扩展得到的类wwHttp

猜你喜欢

转载自blog.csdn.net/andrewniu/article/details/80252968