帝国软件
  设为首页 加入收藏 关于我们
 
解密帝国网站管理系统v4.6
栏 目:
 
您的位置:首页 > 技术文档 > ASP.NET编程 >
用 WebClient.UploadData 方法 上载文件数据
作者:宝玉 发布时间:2005-05-12 来源:ASPCOOL
     假如某网站有个表单,例如(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 + "--rn"; //结束边界
   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>
   /// -----------------------------7d52ee27210a3crnContent-Disposition: form-data; name="表单名"rnrn表单值rn
   /// </remarks>
   public byte[] CreateFieldData(string fieldName, string fieldValue)
   ...{
   string textTemplate = Boundary + "rnContent-Disposition: form-data; name="{0}"rnrn{1}rn";
   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 = "rn";
   string textTemplate = Boundary + "rnContent-Disposition: form-data; name="{0}"; filename="{1}"rnContent-Type: {2}rnrn";
  
   // 头数据
   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); // rn
  
   return fieldData;
   }
  
  
   属性#region 属性
   public string Boundary
   ...{
   get
   ...{
   string[] bArray, ctArray;
   string contentType = ContentType;
   ctArray = contentType.Split(';');
   if (ctArray[0].Trim().ToLower() == "multipart/form-data")
   ...{
   bArray = ctArray[1].Split('=');
   return "--" + bArray[1];
   }
   return null;
   }
   }
  
   public string ContentType
   ...{
   get ...{
   if (HttpContext.Current == null)
   ...{
   return "multipart/form-data; boundary=---------------------------7d5b915500cee";
   }
   return HttpContext.Current.Request.ContentType;
   }
   }
   #endregion
   }
  }
  
  
  在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;
   }
  
   }
   }
  }
  
  
  完整的代码见附件: UploadData.rar(38K)(http://bbs.openlab.net.cn/PostAttachment.aspx?PostID=400927),解压后给web目录建个虚拟目录"UploadData",其中UploadAvatar.aspx是实际的上传处理页,如果上传成功,则返回文件名和文件类型等信息。default.aspx是asp.net页面来调用 WebClient.UploadData方法提交数据,UploadDataWin项目则是winform程序调用。
  
  宝玉的blog: http://blog.joycode.com/dotey
  
  
  

  
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·用 WSH 想ASP 一样 查询数据库  (2005-03-12)
 ·利用 WSH 作定时工作流程  (2005-03-12)

   栏目导行
  PHP编程
  ASP编程
  ASP.NET编程
  JAVA编程
   站点最新
·致合作伙伴的欢迎信
·媒体报道
·帝国软件合作伙伴计划协议
·帝国网站管理系统采集使用教程
·帝国网站管理系统模板制作教程
·帝国CMS模板下载
·Discuz6.0.1UC版通行证发布
·帝国网站管理系统之网站迁移教程
·帝国网站管理系统实例入门教程下载
·《帝国网站管理系统》实例入门教程
   类别最新
·ASP.NET中为DataGrid添加合计字段
·.text urlRewrite介绍
·利用 ASP.NET 的内置功能抵御 Web
·ASP.NET Cache
·用 WebClient.UploadData 方法 上载
·ASP.NET 程序设计-序
·什么是客户端/伺服端(Client/Serve
·因特网应用程序的开发
·网页的种类
·.NET Framework-Microsoft Visual
 
关于帝国 | 广告服务 | 联系我们 | 程序开发 | 网站地图 | 留言板 帝国网站管理系统