search了非常多的文章,總算勉強實現了。有許多不完善的地方。
在HCLoad.Web項目下新建目錄Pics復制一張圖片到根目錄下。
圖片名:Bubble.jpg 右擊->屬性->生成操作:Resource
UC_UpDown.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< UserControl x:Class = "HCLoad.UC_UpDown" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Width = "500" Height = "500" > < StackPanel Background = "White" Height = "450" > < Button Content = "down" Click = "Button_Click" ></ Button > < HyperlinkButton Content = "下載保存" NavigateUri = "http://localhost:4528/download.ashx?fileName=aa.txt" TargetName = "_self" x:Name = "lBtnDown" /> < TextBlock x:Name = "tbMsgString" Text = "下載進度" TextAlignment = "Center" Foreground = "Green" ></ TextBlock > < Button x:Name = "btnDownload" Content = "DownLoad Pictures" Width = "150" Height = "35" Margin = "15" Click = "btnDownload_Click" /> < Border Background = "Wheat" BorderThickness = "5" Width = "400" Height = "280" > < Image x:Name = "imgDownLoad" Width = "400" Height = "300" Margin = "15" Stretch = "Fill" /> </ Border > < Button x:Name = "btnUpLoad" Content = "UpLoad Pictures" Width = "150" Height = "35" Margin = "15" Click = "btnUpLoad_Click" /> </ StackPanel > </ UserControl > |
UC_UpDown.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Windows.Media.Imaging; //因為要使用BitmapImage using System.IO; //因為要使用Stream namespace HCLoad { public partial class UC_UpDown : UserControl { //1、WebClient 對象一次只能啟動一個請求。如果在一個請求完成(包括出錯和取消)前,即IsBusy為true時,進行第二個請求,則第二個請求將會拋出 NotSupportedException 類型的異常 //2、如果 WebClient 對象的 BaseAddress 屬性不為空,則 BaseAddress 與 URI(相對地址) 組合在一起構成絕對 URI //3、WebClient 類的 AllowReadStreamBuffering 屬性:是否對從 Internet 資源接收的數據做緩沖處理。默認值為true,將數據緩存在客戶端內存中,以便隨時被應用程序讀取 //獲取選定圖片信息 System.IO.FileInfo fileinfo; public UC_UpDown() { InitializeComponent(); } #region 下載圖片 private void btnDownload_Click( object sender, RoutedEventArgs e) { //向指定的Url發送下載流數據請求 String imgUrl = "http://localhost:4528/Bubble.jpg" ; Uri endpoint = new Uri(imgUrl); WebClient client = new WebClient(); client.OpenReadCompleted += new OpenReadCompletedEventHandler(OnOpenReadCompleted); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(clientDownloadStream_DownloadProgressChanged); client.OpenReadAsync(endpoint); } void OnOpenReadCompleted( object sender, OpenReadCompletedEventArgs e) { //OpenReadCompletedEventArgs.Error - 該異步操作期間是否發生了錯誤 //OpenReadCompletedEventArgs.Cancelled - 該異步操作是否已被取消 //OpenReadCompletedEventArgs.Result - 下載后的 Stream 類型的數據 //OpenReadCompletedEventArgs.UserState - 用戶標識 if (e.Error != null ) { MessageBox.Show(e.Error.ToString()); return ; } if (e.Cancelled != true ) { //獲取下載的流數據(在此處是圖片數據)并顯示在圖片控件中 //Stream stream = e.Result; //BitmapImage bitmap = new BitmapImage(); //bitmap.SetSource(stream); //imgDownLoad.Source = bitmap; Stream clientStream = e.UserState as Stream; Stream serverStream = (Stream)e.Result; byte [] buffer = new byte [serverStream.Length]; serverStream.Read(buffer, 0, buffer.Length); clientStream.Write(buffer, 0, buffer.Length); clientStream.Close(); serverStream.Close(); } } void clientDownloadStream_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e) { //DownloadProgressChangedEventArgs.ProgressPercentage - 下載完成的百分比 //DownloadProgressChangedEventArgs.BytesReceived - 當前收到的字節數 //DownloadProgressChangedEventArgs.TotalBytesToReceive - 總共需要下載的字節數 //DownloadProgressChangedEventArgs.UserState - 用戶標識 this .tbMsgString.Text = string .Format( "完成百分比:{0} 當前收到的字節數:{1} 資料大小:{2} " , e.ProgressPercentage.ToString() + "%" , e.BytesReceived.ToString(), e.TotalBytesToReceive.ToString()); } #endregion #region 上傳圖片 private void btnUpLoad_Click( object sender, RoutedEventArgs e) { /**/ /* * OpenWriteCompleted - 在打開用于上傳的流完成時(包括取消操作及有錯誤發生時)所觸發的事件 * WriteStreamClosed - 在寫入數據流的異步操作完成時(包括取消操作及有錯誤發生時)所觸發的事件 * UploadProgressChanged - 上傳數據過程中所觸發的事件。如果調用 OpenWriteAsync() 則不會觸發此事件 * Headers - 與請求相關的的標頭的 key/value 對** * OpenWriteAsync(Uri address, string method, Object userToken) - 打開流以使用指定的方法向指定的 URI 寫入數據 * Uri address - 接收上傳數據的 URI * string method - 所使用的 HTTP 方法(POST 或 GET) * Object userToken - 需要上傳的數據流 */ OpenFileDialog openFileDialog = new OpenFileDialog() { //彈出打開文件對話框要求用戶自己選擇在本地端打開的圖片文件 Filter = "Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*" , Multiselect = false //不允許多選 }; if (openFileDialog.ShowDialog() == true ) //.DialogResult.OK) { //fileinfo = openFileDialog.Files; //取得所選擇的文件,其中Name為文件名字段,作為綁定字段顯示在前端 fileinfo = openFileDialog.File; if (fileinfo != null ) { WebClient webclient = new WebClient(); string uploadFileName = fileinfo.Name.ToString(); //獲取所選文件的名字 #region 把圖片上傳到服務器上 Uri upTargetUri = new Uri(String.Format( "http://localhost:4528/WebClientUpLoadStreamHandler.ashx?fileName={0}" , uploadFileName), UriKind.Absolute); //指定上傳地址 webclient.OpenWriteCompleted += new OpenWriteCompletedEventHandler(webclient_OpenWriteCompleted); webclient.Headers[ "Content-Type" ] = "multipart/form-data" ; webclient.OpenWriteAsync(upTargetUri, "POST" , fileinfo.OpenRead()); webclient.WriteStreamClosed += new WriteStreamClosedEventHandler(webclient_WriteStreamClosed); #endregion } else { MessageBox.Show( "請選取想要上載的圖片!!!" ); } } } void webclient_OpenWriteCompleted( object sender, OpenWriteCompletedEventArgs e) { //將圖片數據流發送到服務器上 // e.UserState - 需要上傳的流(客戶端流) Stream clientStream = e.UserState as Stream; // e.Result - 目標地址的流(服務端流) Stream serverStream = e.Result; byte [] buffer = new byte [4096]; int readcount = 0; // clientStream.Read - 將需要上傳的流讀取到指定的字節數組中 while ((readcount = clientStream.Read(buffer, 0, buffer.Length)) > 0) { // serverStream.Write - 將指定的字節數組寫入到目標地址的流 serverStream.Write(buffer, 0, readcount); } serverStream.Close(); clientStream.Close(); } void webclient_WriteStreamClosed( object sender, WriteStreamClosedEventArgs e) { //判斷寫入是否有異常 if (e.Error != null ) { System.Windows.Browser.HtmlPage.Window.Alert(e.Error.Message.ToString()); } else { System.Windows.Browser.HtmlPage.Window.Alert( "圖片上傳成功!!!" ); } } #endregion private void Button_Click( object sender, RoutedEventArgs e) { //這種方法搞不定,好像提示跨域操作。 //提示:錯誤:Unhandled Error in Silverlight Application 跨線程訪問無效。 //Uri upTargetUri = new Uri(String.Format("http://localhost:4528/download.ashx?filename={0}", "123.jpg"), UriKind.Absolute); //指定上傳地址 //WebRequest request = WebRequest.Create(upTargetUri); //request.Method = "GET"; //request.ContentType = "application/octet-stream"; //request.BeginGetResponse(new AsyncCallback(RequestReady), request); //通過調用js代碼下載,比較簡單。 System.Windows.Browser.HtmlPage.Window.Eval( "window.location.href='http://localhost:4528/download.ashx?filename=123.jpg';" ); } void RequestReady(IAsyncResult asyncResult) { MessageBox.Show( "RequestComplete" ); } } } |
在HCLoad.Web項目下新建WebClientUpLoadStreamHandler.ashx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; //因為要用到Stream namespace HCLoad.Web { public class WebClientUpLoadStreamHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //獲取上傳的數據流 string fileNameStr = context.Request.QueryString[ "fileName" ]; Stream sr = context.Request.InputStream; try { string filename = "" ; filename = fileNameStr; byte [] buffer = new byte [4096]; int bytesRead = 0; //將當前數據流寫入服務器端文件夾ClientBin下 string targetPath = context.Server.MapPath( "Pics/" + filename + ".jpg" ); using (FileStream fs = File.Create(targetPath, 4096)) { while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) > 0) { //向文件中寫信息 fs.Write(buffer, 0, bytesRead); } } context.Response.ContentType = "text/plain" ; context.Response.Write( "上傳成功" ); } catch (Exception e) { context.Response.ContentType = "text/plain" ; context.Response.Write( "上傳失敗, 錯誤信息:" + e.Message); } finally { sr.Dispose(); } } public bool IsReusable { get { return false ; } } } } |
新建download.ashx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Net; namespace HCLoad.Web { /// <summary> /// $codebehindclassname$ 的摘要說明 /// </summary> public class download : IHttpHandler { private long ChunkSize = 102400; //100K 每次讀取文件,只讀取100K,這樣可以緩解服務器的壓力 public void ProcessRequest(HttpContext context) { //string fileName = "123.jpg";//客戶端保存的文件名 String fileName = context.Request.QueryString[ "filename" ]; string filePath = context.Server.MapPath( "Bubble.jpg" ); System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath); if (fileInfo.Exists == true ) { byte [] buffer = new byte [ChunkSize]; context.Response.Clear(); System.IO.FileStream iStream = System.IO.File.OpenRead(filePath); long dataLengthToRead = iStream.Length; //獲得下載文件的總大小 context.Response.ContentType = "application/octet-stream" ; //通知瀏覽器下載文件而不是打開 context.Response.AddHeader( "Content-Disposition" , "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); while (dataLengthToRead > 0 && context.Response.IsClientConnected) { int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize)); //讀取的大小 context.Response.OutputStream.Write(buffer, 0, lengthRead); context.Response.Flush(); dataLengthToRead = dataLengthToRead - lengthRead; } context.Response.Close(); context.Response.End(); } //context.Response.ContentType = "text/plain"; //context.Response.Write("Hello World"); } public bool IsReusable { get { return false ; } } } } |
參考:
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/26/1554056.html
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
http://www.cnblogs.com/wmt1708/archive/2009/03/07/1405009.html
http://topic.csdn.net/u/20090918/10/5e41ab52-f514-46b5-ae6a-d69ddb197213.html
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
http://www.cnblogs.com/gwazy/archive/2009/04/02/1427781.html
http://www.cnblogs.com/ewyb/archive/2009/12/10/1621020.html
http://blog.csdn.net/emily1900/archive/2010/06/08/5655726.aspx