用WebClient.UploadData方法上载文件数据的方法

假如某网站有个表单,例如(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程序调用。

(0)

相关推荐

  • C# WebClient类用法实例

    进来的项目中要实现能够在windows service中调用指定项目的链接页面.由于访问页面时候使用的是ie浏览器或其他浏览器,所以想起用webclient类. 如果只想从特定的URI请求文件,则使用WebClient,它是最简单的.NET类,它只用一两条命令执行基本操作,.NET FRAMEWORK目前支持以http:.https和file:标识符开头的uri. WebClient下载文件 使用webclient下载文件有两种方法,具体使用哪一种方法取决于文件内容的处理方式,如果只想把文件保存

  • 基于WebClient实现Http协议的Post与Get对网站进行模拟登陆和浏览实例

    本文实例讲述了基于WebClient实现Http协议的Post与Get对网站进行模拟登陆和浏览的方法.分享给大家供大家参考.具体分析如下: 一.问题: 我们在一些场合经常需要模拟浏览器进行一些操作,比如模拟投票,或者模拟点击,或者Web游戏外挂. 二.解决方法: C#中封装好的WebClient可以在某些要求不算高的场景实现Http的Post和Get.具体请见如下代码: 复制代码 代码如下: using System; using System.Collections.Generic; usin

  • C# webclient中文乱码问题解决方法

    webclient在调用DownloadData或者DownloadString的时候请求回来的数据出现乱码问题,解决办法如下: 1.设置webclient的编码格式为目标编码格式 复制代码 代码如下: WebClient web = new WebClient();//创建webclient对象 web.Encoding = System.Text.Encoding.UTF8;//定义对象语言 string returns = web.DownloadString("_http://www.w

  • silverlight用webclient大文件上传的实例代码

    客户端: 复制代码 代码如下: /// <summary>      /// 写入数据到流中      /// </summary>      /// <param name="url"></param>      /// <param name="callback"></param>      public async static Task<bool> Write(string

  • C#中在WebClient中使用post发送数据实现方法

    很多时候,我们需要使用C#中的WebClient 来收发数据,WebClient 类提供向 URI 标识的任何本地.Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法.本文就较为详细的说明了WebClient中使用post发送数据实现方法. 下面先说说WebClient 最主要的功能. WebClient 构造函数 .Ctor 包括 一个空构造函数 和一个静态构造函数, 静态构造函数主要为UrlEncode 和UrlEncodeAndWirte 编码提供参照by

  • Silverlight中同步调用WebClient的解决办法,是同步!

    代码如下: 复制代码 代码如下: private void button2_Click(object sender, RoutedEventArgs e) { Service1Client sc = new Service1Client(); sc.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(sc_DoWorkCompleted); sc.DoWorkAsync(textBox1.Text); } void sc_

  • 用WebClient.UploadData方法上载文件数据的方法

    假如某网站有个表单,例如(url: http://localhost/login.aspx):  帐号  密码 我们需要在程序中提交数据到这个表单,对于这种表单,我们可以使用 WebClient.UploadData 方法来实现,将所要上传的数据拼成字符即可,程序很简单: string uriString = "http://localhost/login.aspx";  // 创建一个新的 WebClient 实例.  WebClient myWebClient = new WebC

  • ajax读取properties资源文件数据的方法

    本文实例讲述了ajax读取properties资源文件数据的方法.分享给大家供大家参考.具体实现方法如下: properties资源文件的内容如下: hello=englishww name=english zk emailEmpty=Field cannot be empty! emailInvalid=Invalid email address! js调用ajax处理代码: $.ajax({ type:'POST', dataType:'json', url:'/jeecms/jeecms/

  • C#使用FileStream循环读取大文件数据的方法示例

    本文实例讲述了C#使用FileStream循环读取大文件数据的方法.分享给大家供大家参考,具体如下: 今天学习了FileStream的用法,用来读取文件流,教程上都是读取小文件,一次性读取,但是如果遇到大文件,那么我们就需要循环读取文件. 直接上代码. 引用命名空间 using System.IO; 下面就是循环读取大文件的代码 class Program { static void Main(string[] args) { //循环读取大文本文件 FileStream fsRead; //获

  • JavaScript实现读取与输出XML文件数据的方法示例

    本文实例讲述了JavaScript实现读取与输出XML文件数据的方法.分享给大家供大家参考,具体如下: 一.介绍 通过JavaScript读取XML文档中数据的方法很多. 其根本的思路就是:首先在后台加载XML文档,然后通过JavaScript获取文档中所需的数据,最后应用HTML展示获取的数据. 二.获取XML元素的属性值的应用 下面应用attributes属性和getNamedItem()方法获取一个指定的XML文档中的属性值. 三.代码 首先创建一个XML文档,并且为指定的元素设置属性,程

  • Python读取txt文件数据的方法(用于接口自动化参数化数据)

    小试牛刀: 1.需要python如何读取文件 2.需要python操作list 3.需要使用split()对字符串进行分割 代码运行截图 : 代码(copy) #encoding=utf-8 #1.range中填写的数据 跟txt中行数保持一致 默认按照空格分隔 f_space = open(r"C:\Users\Administrator\Desktop\Space.txt","r") line_space = f_space.readlines() for i

  • C#读取txt文件数据的方法实例

    第一步新建txt文件,写入内容 我是放在D盘下的,数据以逗号隔开的,是英文逗号 第二步读取数据 在需要读取数据的页面,添加代码,就可以了 private void Phone_Load(object sender, EventArgs e) { string ReadLine; string[] array; string Path = @"D:\FrontierApp.TXT"; StreamReader reader = new StreamReader(Path,System.T

  • springboot读取application.yaml文件数据的方法

    本文实例为大家分享了springboot读取application.yaml文件数据的具体代码,供大家参考,具体内容如下 提示:以下是本篇文章正文内容,下面案例可供参考 一.创建并编辑对应的文件 1.application.yaml !!!这里一定要注意,datasource一定不能写成dataSource,因为会和Spring内部的产生冲突 server:   port: 8080 contry: china user:   - name: zhangsan     age: 18   - n

  • mssqlserver恢复ldf文件数据的方法

    我们重要的数据是存放在MDF文件中的,如果LDF文件丢失,MDF文件没有丢失,那么数据也可以还原.如果LDF文件没有丢失,MDF文件丢失,且LDF文件是完整的,也是可以提供一定手段还原数据.现象描述我们现在要面对的问题是,针对wtlog_2008_m12这个数据库,只有MDF文件而LDF文件丢失了,SQL Server Management Studio中也没有这个数据库,附加上也会提示错误.解决方法(1)在SQL Server Management Studio删除状态为Recovery Pe

  • Python pandas DataFrame数据拼接方法

    目录 前言 DataFrame数据拼接方法一:使用.append()方法. DataFrame数据拼接方法二:使用.concat()方法. 补充:Python同时合并多个DataFrame 总结 前言 在pandas模块中,通常我们都需要对类型为DataFrame的数据进行操作,其中最为常见的操作便是拼接了.比如我们将两个Excel表格中的数据读入,随后拼接完成后保存进一个新的Excel表格文件中.之前查找了相关的博客, 发现网络上鱼龙混杂.有些代码完全无法执行,为了提高效率,这里做一个详细地记

随机推荐