首页 > 代码库 > [C#]使用WebClient上传文件并同时Post表单数据字段到服务端

[C#]使用WebClient上传文件并同时Post表单数据字段到服务端

转自:http://www.97world.com/archives/2963

   之前遇到一个问题,就是使用WebClient上传文件的同时,还要Post表单数据字段,一开始以为WebClient可以直接做到,结果发现如果先Post表单字段,就只能获取到字段及其值,如果先上传文件,也只能获取到上传文件的内容。测试了不少时间才发现WebClient不能这么使用。

    Google到相关的解决思路和类,因为发现网上的一些文章不是介绍得太简单就是太复杂,所以这里简单整理一下,既能帮助自己巩固知识,也希望能够帮到大家!如果大家有什么不明白,可以直接留言问我。

    关于WebClient上传文件并同时Post表单数据的实现原理,大家可以参考这篇文章http://www.cnblogs.com/goody9807/archive/2007/06/06/773735.html,介绍得非常详细,但是类和实例有些模糊,所以类和实例可以直接参考本文。

HttpRequestClient类Code:
帮助
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net;
 
namespace Common.Helper
{
  /// <summary>
  /// description:http post请求客户端
  /// last-modified-date:2012-02-28
  /// </summary>
  public class HttpRequestClient
  {
    #region //字段
    private ArrayList bytesArray;
    private Encoding encoding = Encoding.UTF8;
    private string boundary = String.Empty;
    #endregion
 
    #region //构造方法
    public HttpRequestClient()
    {
      bytesArray = new ArrayList();
      string flag = DateTime.Now.Ticks.ToString("x");
      boundary = "---------------------------" + flag;
    }
    #endregion
 
    #region //方法
    /// <summary>
    /// 合并请求数据
    /// </summary>
    /// <returns></returns>
    private byte[] MergeContent()
    {
      int length = 0;
      int readLength = 0;
      string endBoundary = "--" + boundary + "--\r\n";
      byte[] endBoundaryBytes = encoding.GetBytes(endBoundary);
 
      bytesArray.Add(endBoundaryBytes);
 
      foreach (byte[] b in bytesArray)
      {
        length += b.Length;
      }
 
      byte[] bytes = new byte[length];
 
      foreach (byte[] b in bytesArray)
      {
        b.CopyTo(bytes, readLength);
        readLength += b.Length;
      }
 
      return bytes;
    }
 
    /// <summary>
    /// 上传
    /// </summary>
    /// <param name="requestUrl">请求url</param>
    /// <param name="responseText">响应</param>
    /// <returns></returns>
    public bool Upload(String requestUrl, out String responseText)
    {
      WebClient webClient = new WebClient();
      webClient.Headers.Add("Content-Type""multipart/form-data; boundary=" + boundary);
 
      byte[] responseBytes;
      byte[] bytes = MergeContent();
 
      try
      {
        responseBytes = webClient.UploadData(requestUrl, bytes);
        responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
        return true;
      }
      catch (WebException ex)
      {
        Stream responseStream = ex.Response.GetResponseStream();
        responseBytes = new byte[ex.Response.ContentLength];
        responseStream.Read(responseBytes, 0, responseBytes.Length);
      }
      responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
      return false;
    }
 
    /// <summary>
    /// 设置表单数据字段
    /// </summary>
    /// <param name="fieldName">字段名</param>
    /// <param name="fieldValue">字段值</param>
    /// <returns></returns>
    public void SetFieldValue(String fieldName, String fieldValue)
    {
      string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
      string httpRowData = http://www.mamicode.com/String.Format(httpRow, fieldName, fieldValue);
 
      bytesArray.Add(encoding.GetBytes(httpRowData));
    }
 
    /// <summary>
    /// 设置表单文件数据
    /// </summary>
    /// <param name="fieldName">字段名</param>
    /// <param name="filename">字段值</param>
    /// <param name="contentType">内容内型</param>
    /// <param name="fileBytes">文件字节流</param>
    /// <returns></returns>
    public void SetFieldValue(String fieldName, String filename, String contentType, Byte[] fileBytes)
    {
      string end = "\r\n";
      string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
      string httpRowData = http://www.mamicode.com/String.Format(httpRow, fieldName, filename, contentType);
 
      byte[] headerBytes = encoding.GetBytes(httpRowData);
      byte[] endBytes = encoding.GetBytes(end);
      byte[] fileDataBytes = new byte[headerBytes.Length + fileBytes.Length + endBytes.Length];
 
      headerBytes.CopyTo(fileDataBytes, 0);
      fileBytes.CopyTo(fileDataBytes, headerBytes.Length);
      endBytes.CopyTo(fileDataBytes, headerBytes.Length + fileBytes.Length);
 
      bytesArray.Add(fileDataBytes);
    }
    #endregion
  }
}
客户端实例代码:
帮助
01
02
03
04
05
06
07
08
09
10
string fileFullName=@"c:\test.txt",filedValue=http://www.mamicode.com/"hello_world",responseText = "";
FileStream fs = new FileStream(fileFullName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] fileBytes = new byte[fs.Length];
fs.Read(fileBytes, 0, fileBytes.Length);
fs.Close(); fs.Dispose();
 
HttpRequestClient httpRequestClient = new HttpRequestClient();
httpRequestClient.SetFieldValue("key", filedValue);
httpRequestClient.SetFieldValue("uploadfile", Path.GetFileName(fileFullName), "application/octet-stream", fileBytes);
httpRequestClient.Upload(NormalBotConfig.Instance.GetUploadFileUrl(), out responseText);
服务端实例代码:
帮助
1
2
3
4
5
6
7
8
if (HttpContext.Current.Request.Files.AllKeys.Length > 0)
{
  string filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "UploadFile", DateTime.Now.Year.ToString(), DateTime.Now.Month.ToString(), DateTime.Now.Day.ToString());
  if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
  //这里我直接用索引来获取第一个文件,如果上传了多个文件,可以通过遍历HttpContext.Current.Request.Files.AllKeys取“key值”,再通过HttpContext.Current.Request.Files[“key值”]获取文件
  HttpContext.Current.Request.Files[0].SaveAs(Path.Combine(filePath, HttpContext.Current.Request.Files[0].FileName));
  string filedValue = http://www.mamicode.com/HttpContext.Current.Request.Form["key"];
}

 

使用WebClient或HttpWebRequest模拟上传文件和数据

假如某网站有个表单,例如(url: http://localhost/login.aspx):
技术分享帐号  
技术分享密码  
技术分享
技术分享我们需要在程序中提交数据到这个表单,对于这种表单,我们可以使用 WebClient.UploadData 方法来实现,将所要上传的数据拼成字符即可,程序很简单:
技术分享
技术分享string uriString = "http://localhost/login.aspx";
技术分享// 创建一个新的 WebClient 实例.
技术分享WebClient myWebClient = new WebClient();
技术分享string postData = "Username=admin&Password=admin";
技术分享// 注意这种拼字符串的ContentType
技术分享myWebClient.Headers.Add("Content-Type","application/x-www-form-urlencoded");
技术分享// 转化成二进制数组
技术分享byte[] byteArray = Encoding.ASCII.GetBytes(postData);
技术分享// 上传数据,并获取返回的二进制数据.
技术分享byte[] responseArray = myWebClient.UploadData(uriString,"POST",byteArray);
技术分享
技术分享
技术分享对于文件上传类的表单,例如(url: http://localhost/uploadFile.aspx):
技术分享文件  
技术分享
技术分享对于这种表单,我们可以使用
技术分享String uriString = "http://localhost/uploadFile.aspx";
技术分享
技术分享// 创建一个新的 WebClient 实例.
技术分享WebClient myWebClient = new WebClient();
技术分享
技术分享string fileName = @"C:\upload.txt";
技术分享
技术分享// 直接上传,并获取返回的二进制数据.
技术分享byte[] responseArray = myWebClient.UploadFile(uriString,"POST",fileName);
技术分享
技术分享
技术分享还有一种表单,不仅有文字,还有文件,例如(url: http://localhost/uploadData.aspx):
技术分享文件名  
技术分享文件  
技术分享
技术分享对于这种表单,似乎前面的两种方法都不能适用,对于第一种方法,不能直接拼字符串,对于第二种,我们只能传文件,重新回到第一个方法,注意参数:
技术分享public byte[] UploadData(
技术分享   string address,
技术分享   string method,
技术分享   byte[] data
技术分享);
技术分享在第一个例子中,是通过拼字符串来得到byte[] data参数值的,对于这种表单显然不行,反过来想想,对于uploadData.aspx这样的程序来说,直接通过网页提交数据,后台所获取到的流是什么样的呢?(在我以前的一篇blog中,曾分析过这个问题:asp无组件上传进度条解决方案),最终的数据如下:
技术分享
技术分享-----------------------------7d429871607fe
技术分享Content-Disposition: form-data; name="file1"; filename="G:\homepage.txt"
技术分享Content-Type: text/plain
技术分享宝玉:http://www.webuc.net
技术分享-----------------------------7d429871607fe
技术分享Content-Disposition: form-data; name="filename"
技术分享default filename
技术分享-----------------------------7d429871607fe--
技术分享
技术分享
技术分享所以只要拼一个这样的byte[] data数据Post过去,就可以达到同样的效果了。但是一定要注意,对于这种带有文件上传的,其ContentType是不一样的,例如上面的这种,其ContentType为"multipart/form-data; boundary=---------------------------7d429871607fe"。有了ContentType,我们就可以知道boundary(就是上面的"---------------------------7d429871607fe"),知道boundary了我们就可以构造出我们所需要的byte[] data了,最后,不要忘记,把我们构造的ContentType传到WebClient中(例如:webClient.Headers.Add("Content-Type", ContentType);)这样,就可以通过WebClient.UploadData 方法上载文件数据了。
技术分享
技术分享具体代码如下:
技术分享生成二进制数据类的封装
技术分享
技术分享using System;
技术分享using System.Web;
技术分享using System.IO;
技术分享using System.Net;
技术分享using System.Text;
技术分享using System.Collections;
技术分享
技术分享namespace UploadData.Common
技术分享技术分享{
技术分享    /**//// <summary>
技术分享    /// 创建WebClient.UploadData方法所需二进制数组
技术分享    /// </summary>
技术分享    public class CreateBytes
技术分享    技术分享{
技术分享        Encoding encoding = Encoding.UTF8;
技术分享
技术分享        /**//// <summary>
技术分享        /// 拼接所有的二进制数组为一个数组
技术分享        /// </summary>
技术分享        /// <param name="byteArrays">数组</param>
技术分享        /// <returns></returns>
技术分享        /// <remarks>加上结束边界</remarks>
技术分享        public byte[] JoinBytes(ArrayList byteArrays)
技术分享        技术分享{
技术分享            int length = 0;
技术分享            int readLength = 0;
技术分享
技术分享            // 加上结束边界
技术分享            string endBoundary = Boundary + "--\r\n"; //结束边界
技术分享            byte[] endBoundaryBytes = encoding.GetBytes(endBoundary);
技术分享            byteArrays.Add(endBoundaryBytes);
技术分享
技术分享            foreach(byte[] b in byteArrays)
技术分享            技术分享{
技术分享                length += b.Length;
技术分享            }
技术分享            byte[] bytes = new byte[length];
技术分享
技术分享            // 遍历复制
技术分享            //
技术分享            foreach(byte[] b in byteArrays)
技术分享            技术分享{
技术分享                b.CopyTo(bytes, readLength);
技术分享                readLength += b.Length;
技术分享            }
技术分享
技术分享            return bytes;
技术分享        }
技术分享
技术分享        public bool UploadData(string uploadUrl, byte[] bytes, out byte[] responseBytes)
技术分享        技术分享{
技术分享            WebClient webClient = new WebClient();
技术分享            webClient.Headers.Add("Content-Type", ContentType);
技术分享
技术分享            try
技术分享            技术分享{
技术分享                responseBytes = webClient.UploadData(uploadUrl, bytes);
技术分享                return true;
技术分享            }
技术分享            catch (WebException ex)
技术分享            技术分享{
技术分享                Stream resp = ex.Response.GetResponseStream();
技术分享                responseBytes = new byte[ex.Response.ContentLength];
技术分享                resp.Read(responseBytes, 0, responseBytes.Length);                
技术分享            }
技术分享            return false; 
技术分享        }
技术分享
技术分享
技术分享
技术分享        /**//// <summary>
技术分享        /// 获取普通表单区域二进制数组
技术分享        /// </summary>
技术分享        /// <param name="fieldName">表单名</param>
技术分享        /// <param name="fieldValue">表单值</param>
技术分享        /// <returns></returns>
技术分享        /// <remarks>
技术分享        /// -----------------------------7d52ee27210a3c\r\nContent-Disposition: form-data; name=\"表单名\"\r\n\r\n表单值\r\n
技术分享        /// </remarks>
技术分享        public byte[] CreateFieldData(string fieldName, string fieldValue)
技术分享        技术分享{
技术分享            string textTemplate = Boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
技术分享            string text = String.Format(textTemplate, fieldName, fieldValue);
技术分享            byte[] bytes = encoding.GetBytes(text);
技术分享            return bytes;
技术分享        }
技术分享
技术分享        
技术分享        /**//// <summary>
技术分享        /// 获取文件上传表单区域二进制数组
技术分享        /// </summary>
技术分享        /// <param name="fieldName">表单名</param>
技术分享        /// <param name="filename">文件名</param>
技术分享        /// <param name="contentType">文件类型</param>
技术分享        /// <param name="contentLength">文件长度</param>
技术分享        /// <param name="stream">文件流</param>
技术分享        /// <returns>二进制数组</returns>
技术分享        public byte[] CreateFieldData(string fieldName, string filename,string contentType, byte[] fileBytes)
技术分享        技术分享{
技术分享            string end = "\r\n";
技术分享            string textTemplate = Boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
技术分享            
技术分享            // 头数据
技术分享            string data = String.Format(textTemplate, fieldName, filename, contentType);
技术分享            byte[] bytes = encoding.GetBytes(data);
技术分享
技术分享            
技术分享
技术分享            // 尾数据
技术分享            byte[] endBytes = encoding.GetBytes(end);
技术分享
技术分享            // 合成后的数组
技术分享            byte[] fieldData = new byte[bytes.Length + fileBytes.Length + endBytes.Length];
技术分享
技术分享            bytes.CopyTo(fieldData, 0); // 头数据
技术分享            fileBytes.CopyTo(fieldData, bytes.Length); // 文件的二进制数据
技术分享            endBytes.CopyTo(fieldData, bytes.Length + fileBytes.Length); // \r\n
技术分享
技术分享            return fieldData;
技术分享        }
技术分享
技术分享
技术分享        属性属性
技术分享    }
技术分享}
技术分享
技术分享
技术分享在Winform中调用
技术分享
技术分享
技术分享using System;
技术分享using System.Drawing;
技术分享using System.Collections;
技术分享using System.ComponentModel;
技术分享using System.Windows.Forms;
技术分享using System.Data;
技术分享
技术分享using UploadData.Common;
技术分享using System.IO;
技术分享
技术分享namespace UploadDataWin
技术分享技术分享{
技术分享    /**//// <summary>
技术分享    /// frmUpload 的摘要说明。
技术分享    /// </summary>
技术分享    public class frmUpload : System.Windows.Forms.Form
技术分享    技术分享{
技术分享        private System.Windows.Forms.Label lblAmigoToken;
技术分享        private System.Windows.Forms.TextBox txtAmigoToken;
技术分享        private System.Windows.Forms.Label lblFilename;
技术分享        private System.Windows.Forms.TextBox txtFilename;
技术分享        private System.Windows.Forms.Button btnBrowse;
技术分享        private System.Windows.Forms.TextBox txtFileData;
技术分享        private System.Windows.Forms.Label lblFileData;
技术分享        private System.Windows.Forms.Button btnUpload;
技术分享        private System.Windows.Forms.OpenFileDialog openFileDialog1;
技术分享        private System.Windows.Forms.TextBox txtResponse;
技术分享        /**//// <summary>
技术分享        /// 必需的设计器变量。
技术分享        /// </summary>
技术分享        private System.ComponentModel.Container components = null;
技术分享
技术分享        public frmUpload()
技术分享        技术分享{
技术分享            //
技术分享            // Windows 窗体设计器支持所必需的
技术分享            //
技术分享            InitializeComponent();
技术分享
技术分享            //
技术分享            // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
技术分享            //
技术分享        }
技术分享
技术分享        /**//// <summary>
技术分享        /// 清理所有正在使用的资源。
技术分享        /// </summary>
技术分享        protected override void Dispose( bool disposing )
技术分享        技术分享{
技术分享            if( disposing )
技术分享            技术分享{
技术分享                if (components != null) 
技术分享                技术分享{
技术分享                    components.Dispose();
技术分享                }
技术分享            }
技术分享            base.Dispose( disposing );
技术分享        }
技术分享
技术分享        Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
技术分享        /**//// <summary>
技术分享        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
技术分享        /// 此方法的内容。
技术分享        /// </summary>
技术分享        private void InitializeComponent()
技术分享        技术分享{
技术分享            this.lblAmigoToken = new System.Windows.Forms.Label();
技术分享            this.txtAmigoToken = new System.Windows.Forms.TextBox();
技术分享            this.lblFilename = new System.Windows.Forms.Label();
技术分享            this.txtFilename = new System.Windows.Forms.TextBox();
技术分享            this.btnBrowse = new System.Windows.Forms.Button();
技术分享            this.txtFileData = new System.Windows.Forms.TextBox();
技术分享            this.lblFileData = new System.Windows.Forms.Label();
技术分享            this.btnUpload = new System.Windows.Forms.Button();
技术分享            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
技术分享            this.txtResponse = new System.Windows.Forms.TextBox();
技术分享            this.SuspendLayout();
技术分享            // 
技术分享            // lblAmigoToken
技术分享            // 
技术分享            this.lblAmigoToken.Location = new System.Drawing.Point(40, 48);
技术分享            this.lblAmigoToken.Name = "lblAmigoToken";
技术分享            this.lblAmigoToken.Size = new System.Drawing.Size(72, 23);
技术分享            this.lblAmigoToken.TabIndex = 0;
技术分享            this.lblAmigoToken.Text = "AmigoToken";
技术分享            // 
技术分享            // txtAmigoToken
技术分享            // 
技术分享            this.txtAmigoToken.Location = new System.Drawing.Point(120, 48);
技术分享            this.txtAmigoToken.Name = "txtAmigoToken";
技术分享            this.txtAmigoToken.Size = new System.Drawing.Size(248, 21);
技术分享            this.txtAmigoToken.TabIndex = 1;
技术分享            this.txtAmigoToken.Text = "";
技术分享            // 
技术分享            // lblFilename
技术分享            // 
技术分享            this.lblFilename.Location = new System.Drawing.Point(40, 96);
技术分享            this.lblFilename.Name = "lblFilename";
技术分享            this.lblFilename.Size = new System.Drawing.Size(80, 23);
技术分享            this.lblFilename.TabIndex = 2;
技术分享            this.lblFilename.Text = "Filename";
技术分享            // 
技术分享            // txtFilename
技术分享            // 
技术分享            this.txtFilename.Location = new System.Drawing.Point(120, 96);
技术分享            this.txtFilename.Name = "txtFilename";
技术分享            this.txtFilename.Size = new System.Drawing.Size(248, 21);
技术分享            this.txtFilename.TabIndex = 3;
技术分享            this.txtFilename.Text = "";
技术分享            // 
技术分享            // btnBrowse
技术分享            // 
技术分享            this.btnBrowse.Location = new System.Drawing.Point(296, 144);
技术分享            this.btnBrowse.Name = "btnBrowse";
技术分享            this.btnBrowse.TabIndex = 4;
技术分享            this.btnBrowse.Text = "浏览技术分享";
技术分享            this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
技术分享            // 
技术分享            // txtFileData
技术分享            // 
技术分享            this.txtFileData.Location = new System.Drawing.Point(120, 144);
技术分享            this.txtFileData.Name = "txtFileData";
技术分享            this.txtFileData.Size = new System.Drawing.Size(168, 21);
技术分享            this.txtFileData.TabIndex = 5;
技术分享            this.txtFileData.Text = "";
技术分享            // 
技术分享            // lblFileData
技术分享            // 
技术分享            this.lblFileData.Location = new System.Drawing.Point(40, 144);
技术分享            this.lblFileData.Name = "lblFileData";
技术分享            this.lblFileData.Size = new System.Drawing.Size(72, 23);
技术分享            this.lblFileData.TabIndex = 6;
技术分享            this.lblFileData.Text = "FileData";
技术分享            // 
技术分享            // btnUpload
技术分享            // 
技术分享            this.btnUpload.Location = new System.Drawing.Point(48, 184);
技术分享            this.btnUpload.Name = "btnUpload";
技术分享            this.btnUpload.TabIndex = 7;
技术分享            this.btnUpload.Text = "Upload";
技术分享            this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click);
技术分享            // 
技术分享            // txtResponse
技术分享            // 
技术分享            this.txtResponse.Location = new System.Drawing.Point(136, 184);
技术分享            this.txtResponse.Multiline = true;
技术分享            this.txtResponse.Name = "txtResponse";
技术分享            this.txtResponse.Size = new System.Drawing.Size(248, 72);
技术分享            this.txtResponse.TabIndex = 8;
技术分享            this.txtResponse.Text = "";
技术分享            // 
技术分享            // frmUpload
技术分享            // 
技术分享            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
技术分享            this.ClientSize = new System.Drawing.Size(400, 269);
技术分享            this.Controls.Add(this.txtResponse);
技术分享            this.Controls.Add(this.btnUpload);
技术分享            this.Controls.Add(this.lblFileData);
技术分享            this.Controls.Add(this.txtFileData);
技术分享            this.Controls.Add(this.btnBrowse);
技术分享            this.Controls.Add(this.txtFilename);
技术分享            this.Controls.Add(this.lblFilename);
技术分享            this.Controls.Add(this.txtAmigoToken);
技术分享            this.Controls.Add(this.lblAmigoToken);
技术分享            this.Name = "frmUpload";
技术分享            this.Text = "frmUpload";
技术分享            this.ResumeLayout(false);
技术分享
技术分享        }
技术分享        #endregion
技术分享
技术分享        /**//// <summary>
技术分享        /// 应用程序的主入口点。
技术分享        /// </summary>
技术分享        [STAThread]
技术分享        static void Main() 
技术分享        技术分享{
技术分享            Application.Run(new frmUpload());
技术分享        }
技术分享
技术分享        private void btnUpload_Click(object sender, System.EventArgs e)
技术分享        技术分享{
技术分享            // 非空检验
技术分享            if (txtAmigoToken.Text.Trim() == "" || txtFilename.Text == "" || txtFileData.Text.Trim() == "")
技术分享            技术分享{
技术分享                MessageBox.Show("Please fill data");
技术分享                return;
技术分享            }
技术分享
技术分享            // 所要上传的文件路径
技术分享            string path = txtFileData.Text.Trim();
技术分享
技术分享            // 检查文件是否存在
技术分享            if (!File.Exists(path)) 
技术分享            技术分享{
技术分享                MessageBox.Show("{0} does not exist!", path);
技术分享                return;
技术分享            }
技术分享
技术分享            // 读文件流
技术分享            FileStream fs = new FileStream(path, FileMode.Open,
技术分享                FileAccess.Read, FileShare.Read);
技术分享            
技术分享            // 这部分需要完善
技术分享            string ContentType = "application/octet-stream";
技术分享            byte[] fileBytes = new byte[fs.Length];
技术分享            fs.Read(fileBytes, 0, Convert.ToInt32(fs.Length));
技术分享
技术分享
技术分享            // 生成需要上传的二进制数组
技术分享            CreateBytes cb = new CreateBytes();
技术分享            // 所有表单数据
技术分享            ArrayList bytesArray = new ArrayList();
技术分享            // 普通表单
技术分享            bytesArray.Add(cb.CreateFieldData("FileName", txtFilename.Text));
技术分享            bytesArray.Add(cb.CreateFieldData("AmigoToken", txtAmigoToken.Text));
技术分享            // 文件表单
技术分享            bytesArray.Add(cb.CreateFieldData("FileData", path
技术分享                                                , ContentType, fileBytes));
技术分享
技术分享            // 合成所有表单并生成二进制数组
技术分享            byte[] bytes = cb.JoinBytes(bytesArray);
技术分享            
技术分享            // 返回的内容
技术分享            byte[] responseBytes;
技术分享            
技术分享            // 上传到指定Url
技术分享            bool uploaded = cb.UploadData("http://localhost/UploadData/UploadAvatar.aspx", bytes, out responseBytes);
技术分享
技术分享            // 将返回的内容输出到文件
技术分享            using (FileStream file = new FileStream(@"c:\response.text", FileMode.Create, FileAccess.Write, FileShare.Read))
技术分享            技术分享{
技术分享                file.Write(responseBytes, 0, responseBytes.Length);
技术分享            }
技术分享
技术分享            txtResponse.Text = System.Text.Encoding.UTF8.GetString(responseBytes);
技术分享
技术分享        }
技术分享
技术分享        private void btnBrowse_Click(object sender, System.EventArgs e)
技术分享        技术分享{
技术分享            if(openFileDialog1.ShowDialog() == DialogResult.OK)
技术分享            技术分享{
技术分享                txtFileData.Text = openFileDialog1.FileName;
技术分享            }
技术分享
技术分享        }
技术分享    }
技术分享}

[C#]使用WebClient上传文件并同时Post表单数据字段到服务端