因项目需要找了很多Winform利用webclient上传文件的方法,但是基本没有太明白,后来经过多方面努力,终于做好了。
背景:C/S结构下用winform想web站点(asp.net)post文件。
服务器:需要一个传统的能post并上传、处理文件的.aspx文件,代码如下:
default2.aspx
1 <%@ page language="C#" autoeventwireup="true" inherits="Default2, App_Web_wnfnivuw" %>
2
3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml" >
6 <head runat="server">
7 <title>无标题页</title>
8 </head>
9 <body>
10 <form id="form1" runat="server" enctype="multipart/form-data">
11 <div>
12 Specify the file to upload:
13 <asp:PlaceHolder id="Place" runat="server">
14 <input id="File1" type="file" runat="Server"/>
15 </asp:PlaceHolder>
16 <p>
17 Save as file name (no path):
18 <input id="Text1"
19 type="text"
20 runat="server" />
21
22 <p>
23 <span id="Span1"
24 style="font: 8pt verdana;"
25 runat="server" />
26
27 <p>
28 <input type=button
29 id="Button1"
30 value="Upload"
31 runat="server" onserverclick="Button1_ServerClick" />
32 </div>
33 </form>
34 </body>
35 </html>
36
2
3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml" >
6 <head runat="server">
7 <title>无标题页</title>
8 </head>
9 <body>
10 <form id="form1" runat="server" enctype="multipart/form-data">
11 <div>
12 Specify the file to upload:
13 <asp:PlaceHolder id="Place" runat="server">
14 <input id="File1" type="file" runat="Server"/>
15 </asp:PlaceHolder>
16 <p>
17 Save as file name (no path):
18 <input id="Text1"
19 type="text"
20 runat="server" />
21
22 <p>
23 <span id="Span1"
24 style="font: 8pt verdana;"
25 runat="server" />
26
27 <p>
28 <input type=button
29 id="Button1"
30 value="Upload"
31 runat="server" onserverclick="Button1_ServerClick" />
32 </div>
33 </form>
34 </body>
35 </html>
36
网页后台代码:
default2.aspx.cs
1 protected void Page_Load(object sender, EventArgs e)
2 {
3 //把request 请求的数据dump 到一个文件中
4 if (Page.IsPostBack)
5 {
6 byte[] b = Request.BinaryRead(Request.ContentLength);
7
8 FileStream fs = new System.IO.FileStream(@"D:\Log.txt", System.IO.FileMode.Create); BinaryWriter sw = new System.IO.BinaryWriter(fs);
9 sw.Write(b);
10 sw.Close();
11 fs.Close();
12 }
13
14
15 }
2 {
3 //把request 请求的数据dump 到一个文件中
4 if (Page.IsPostBack)
5 {
6 byte[] b = Request.BinaryRead(Request.ContentLength);
7
8 FileStream fs = new System.IO.FileStream(@"D:\Log.txt", System.IO.FileMode.Create); BinaryWriter sw = new System.IO.BinaryWriter(fs);
9 sw.Write(b);
10 sw.Close();
11 fs.Close();
12 }
13
14
15 }
button的点击:
default2.aspx.cs
protected void Button1_ServerClick(object sender, EventArgs e)
{
// Get the HtmlInputFile control from the Controls collection
// of the PlaceHolder control.
HtmlInputFile file = (HtmlInputFile)Page.FindControl("File1");
// Make sure a file was submitted.
if (Text1.Value == "")
{
Span1.InnerHtml = "Error: you must enter a file name";
return;
}
// Save file to server.
if (file.PostedFile != null)
{
try
{
file.PostedFile.SaveAs("D:\\" + Text1.Value);
Span1.InnerHtml = "File uploaded successfully to " + "<b>D:\\" + Text1.Value + "</b> on the Web server";
}
catch (Exception exc)
{
Span1.InnerHtml = "Error saving file <b>D:\\" + Text1.Value + "</b><br>" + exc.ToString();
}
}
}
{
// Get the HtmlInputFile control from the Controls collection
// of the PlaceHolder control.
HtmlInputFile file = (HtmlInputFile)Page.FindControl("File1");
// Make sure a file was submitted.
if (Text1.Value == "")
{
Span1.InnerHtml = "Error: you must enter a file name";
return;
}
// Save file to server.
if (file.PostedFile != null)
{
try
{
file.PostedFile.SaveAs("D:\\" + Text1.Value);
Span1.InnerHtml = "File uploaded successfully to " + "<b>D:\\" + Text1.Value + "</b> on the Web server";
}
catch (Exception exc)
{
Span1.InnerHtml = "Error saving file <b>D:\\" + Text1.Value + "</b><br>" + exc.ToString();
}
}
}
C/S客户端“关键”代码:
form2.cs
1 private void btnUpload_Click(object sender, System.EventArgs e)
2 {
3 // 非空检验
4 if (txtAmigoToken.Text.Trim() == "" || txtFilename.Text == "" || txtFileData.Text.Trim() == "")
5 {
6 MessageBox.Show("Please fill data");
7 return;
8 }
9
10 // 所要上传的文件路径
11 string path = txtFileData.Text.Trim();
12
13 // 检查文件是否存在
14 if (!File.Exists(path))
15 {
16 MessageBox.Show("{0} does not exist!", path);
17 return;
18 }
19
20 // 读文件流
21 FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
22 WebClient webClient = new WebClient();
23
24 ///////////////////////////////////////
25 // 打开页面
26 ///////////////////////////////////////
27 byte[] responseData = webClient.DownloadData(txtAmigoToken.Text);
28 string srcString = Encoding.UTF8.GetString(responseData);
29
30 ///////////////////////////////////////
31 // 填写页面并提交
32 ///////////////////////////////////////
33
34 // 获取页面的 VeiwState
35 string viewStateFlag = "id=\"__VIEWSTATE\" value=\"";
36 int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;
37 int j = srcString.IndexOf("\"", i);
38 string viewState = srcString.Substring(i, j - i);
39
40 // 获取页面的 EventValidation
41 string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\"";
42 i = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length;
43 j = srcString.IndexOf("\"", i);
44 string eventValidation = srcString.Substring(i, j - i);
45
46 // 获取页面的 EVENTARGUMENT
47 string eventargumentFlag = "id=\"__EVENTARGUMENT\" value=\"";
48 i = srcString.IndexOf(eventargumentFlag) + eventargumentFlag.Length;
49 j = srcString.IndexOf("\"", i);
50 string eventargument = "";// srcString.Substring(i, j - i);
51
52 // 获取页面的 EVENTTARGET
53 string eventtargetFlag = "id=\"__EVENTTARGET\" value=\"";
54 i = srcString.IndexOf(eventtargetFlag) + eventtargetFlag.Length;
55 j = srcString.IndexOf("\"", i);
56 string eventtarget = "Button1";
57
58 // 这部分需要完善
59 string ContentType = "application/octet-stream";
60 byte[] fileBytes = new byte[fs.Length];
61 fs.Read(fileBytes, 0, Convert.ToInt32(fs.Length));
62
63
64 // 生成需要上传的二进制数组
65 CreateBytes cb = new CreateBytes();
66 // 所有表单数据
67 ArrayList bytesArray = new ArrayList();
68 // 普通表单
69 bytesArray.Add(cb.CreateFieldData("__EVENTTARGET", eventtarget));
70 bytesArray.Add(cb.CreateFieldData("__EVENTARGUMENT", eventargument));
71 bytesArray.Add(cb.CreateFieldData("__VIEWSTATE", viewState));
72 bytesArray.Add(cb.CreateFieldData("__EVENTVALIDATION", eventValidation));
73
74 bytesArray.Add(cb.CreateFieldData("Text1", txtFilename.Text));
75 // 文件表单
76 bytesArray.Add(cb.CreateFieldData("File1", path, ContentType, fileBytes));
77
78 // 合成所有表单并生成二进制数组
79 byte[] bytes = cb.JoinBytes(bytesArray);
80
81 FileStream fs1 = new System.IO.FileStream(@"F:\PostLog.txt", System.IO.FileMode.Append); //把request 请求的数据dump 到一个文件中
82 BinaryWriter sw = new System.IO.BinaryWriter(fs1);
83 sw.Write(bytes);
84 sw.Close();
85 fs1.Close();
86
87 // 返回的内容
88 byte[] responseBytes;
89
90 // 上传到指定Url
91 bool uploaded = cb.UploadData(txtAmigoToken.Text, bytes, out responseBytes);
92
93 // 将返回的内容输出到文件
94 using (FileStream file = new FileStream(@"f:\response.text", FileMode.Create, FileAccess.Write, FileShare.Read))
95 {
96 file.Write(responseBytes, 0, responseBytes.Length);
97 }
98
99 txtResponse.Text = System.Text.Encoding.UTF8.GetString(responseBytes);
100
101 }
102
103 private void btnBrowse_Click(object sender, System.EventArgs e)
104 {
105 if(openFileDialog1.ShowDialog() == DialogResult.OK)
106 {
107 txtFileData.Text = openFileDialog1.FileName;
108 }
109
110 }
2 {
3 // 非空检验
4 if (txtAmigoToken.Text.Trim() == "" || txtFilename.Text == "" || txtFileData.Text.Trim() == "")
5 {
6 MessageBox.Show("Please fill data");
7 return;
8 }
9
10 // 所要上传的文件路径
11 string path = txtFileData.Text.Trim();
12
13 // 检查文件是否存在
14 if (!File.Exists(path))
15 {
16 MessageBox.Show("{0} does not exist!", path);
17 return;
18 }
19
20 // 读文件流
21 FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
22 WebClient webClient = new WebClient();
23
24 ///////////////////////////////////////
25 // 打开页面
26 ///////////////////////////////////////
27 byte[] responseData = webClient.DownloadData(txtAmigoToken.Text);
28 string srcString = Encoding.UTF8.GetString(responseData);
29
30 ///////////////////////////////////////
31 // 填写页面并提交
32 ///////////////////////////////////////
33
34 // 获取页面的 VeiwState
35 string viewStateFlag = "id=\"__VIEWSTATE\" value=\"";
36 int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;
37 int j = srcString.IndexOf("\"", i);
38 string viewState = srcString.Substring(i, j - i);
39
40 // 获取页面的 EventValidation
41 string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\"";
42 i = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length;
43 j = srcString.IndexOf("\"", i);
44 string eventValidation = srcString.Substring(i, j - i);
45
46 // 获取页面的 EVENTARGUMENT
47 string eventargumentFlag = "id=\"__EVENTARGUMENT\" value=\"";
48 i = srcString.IndexOf(eventargumentFlag) + eventargumentFlag.Length;
49 j = srcString.IndexOf("\"", i);
50 string eventargument = "";// srcString.Substring(i, j - i);
51
52 // 获取页面的 EVENTTARGET
53 string eventtargetFlag = "id=\"__EVENTTARGET\" value=\"";
54 i = srcString.IndexOf(eventtargetFlag) + eventtargetFlag.Length;
55 j = srcString.IndexOf("\"", i);
56 string eventtarget = "Button1";
57
58 // 这部分需要完善
59 string ContentType = "application/octet-stream";
60 byte[] fileBytes = new byte[fs.Length];
61 fs.Read(fileBytes, 0, Convert.ToInt32(fs.Length));
62
63
64 // 生成需要上传的二进制数组
65 CreateBytes cb = new CreateBytes();
66 // 所有表单数据
67 ArrayList bytesArray = new ArrayList();
68 // 普通表单
69 bytesArray.Add(cb.CreateFieldData("__EVENTTARGET", eventtarget));
70 bytesArray.Add(cb.CreateFieldData("__EVENTARGUMENT", eventargument));
71 bytesArray.Add(cb.CreateFieldData("__VIEWSTATE", viewState));
72 bytesArray.Add(cb.CreateFieldData("__EVENTVALIDATION", eventValidation));
73
74 bytesArray.Add(cb.CreateFieldData("Text1", txtFilename.Text));
75 // 文件表单
76 bytesArray.Add(cb.CreateFieldData("File1", path, ContentType, fileBytes));
77
78 // 合成所有表单并生成二进制数组
79 byte[] bytes = cb.JoinBytes(bytesArray);
80
81 FileStream fs1 = new System.IO.FileStream(@"F:\PostLog.txt", System.IO.FileMode.Append); //把request 请求的数据dump 到一个文件中
82 BinaryWriter sw = new System.IO.BinaryWriter(fs1);
83 sw.Write(bytes);
84 sw.Close();
85 fs1.Close();
86
87 // 返回的内容
88 byte[] responseBytes;
89
90 // 上传到指定Url
91 bool uploaded = cb.UploadData(txtAmigoToken.Text, bytes, out responseBytes);
92
93 // 将返回的内容输出到文件
94 using (FileStream file = new FileStream(@"f:\response.text", FileMode.Create, FileAccess.Write, FileShare.Read))
95 {
96 file.Write(responseBytes, 0, responseBytes.Length);
97 }
98
99 txtResponse.Text = System.Text.Encoding.UTF8.GetString(responseBytes);
100
101 }
102
103 private void btnBrowse_Click(object sender, System.EventArgs e)
104 {
105 if(openFileDialog1.ShowDialog() == DialogResult.OK)
106 {
107 txtFileData.Text = openFileDialog1.FileName;
108 }
109
110 }
CreateBytes类代码:
updata.cs
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
}
}
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
}
}