zoukankan
html css js c++ java
使用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;
}
属性
属性
#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 窗体设计器生成的代码
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;
}
}
}
}
查看全文
相关阅读:
【QTP】自动化测试:
sql基本语句
【转】ASP.NET网站怎么发布web项目程序和怎么部署
NHibernate的简单例子
解决ehcache的UpdateChecker问题
正则表达式的贪婪与懒惰
Linux查找文件夹名
centos安装lxml和pyspider
如何通过写一个chrome扩展启动本地程序
网页图片滚动效果
原文地址:https://www.cnblogs.com/goody9807/p/773735.html
最新文章
模板
AcWing
AcWing
Southern and Volga Russia Qualifier 2019-2020
2018-2019 ACM-ICPC, Asia Seoul Regional Contest
最长上升子序列
codeforces1198C Matching vs Independent Set 思维
HDU3374 String Problem KMP算法+最小表示法
POJ3176 Cow Bowling dp
洛谷P3435 [POI2006]OKR-Periods of Words KMP算法
热门文章
HDU6183 Color it 动态开点线段树
codeforces1198B Welfare State 线段树或单调栈+二分
文件式快速读取
codeforces1198A MP3 思维+双指针(滑动窗口)
HDU6582 Path 最短路+最小割
基本数据类型(数字&字符串)
day1
第 006 讲: Python之常用操作符
第 005 讲:数据类型
最近搞定两个问题,继续保持
Copyright © 2011-2022 走看看