2、以字元串的形式和流的形式上傳資料
REST.cs(WCF建立的用于示範以字元串的形式和流的形式上傳資料的REST服務)
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Collections.Generic;
using System.Text;
using System.IO;
/// <summary>
/// 提供 REST 服務的類
/// 注:Silverlight隻支援 GET 和 POST
/// </summary>
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class REST
{
/// <summary>
/// 用于示範傳回 JSON(對象) 的 REST 服務
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[OperationContract]
[WebGet(UriTemplate = "User/{name}/json", ResponseFormat = WebMessageFormat.Json)]
public User HelloJson(string name)
{
return new User { Name = name, DayOfBirth = new DateTime(1980, 2, 14) };
}
/// 用于示範傳回 JSON(集合) 的 REST 服務
[WebGet(UriTemplate = "Users/json", ResponseFormat = WebMessageFormat.Json)]
public List<User> HelloJson2()
return new List<User>
{
new User(){ Name = "webabcd01", DayOfBirth = new DateTime(1980, 1, 1) },
new User(){ Name = "webabcd02", DayOfBirth = new DateTime(1980, 2, 2) },
new User(){ Name = "webabcd03", DayOfBirth = new DateTime(1980, 3, 3) },
};
/// 用于示範傳回 XML(對象) 的 REST 服務
[WebGet(UriTemplate = "User/{name}/xml", ResponseFormat = WebMessageFormat.Xml)]
public User HelloXml(string name)
/// 用于示範傳回 XML(集合) 的 REST 服務
[WebGet(UriTemplate = "Users/xml", ResponseFormat = WebMessageFormat.Xml)]
public List<User> HelloXml2()
/// 用于示範以字元串的形式上傳資料的 REST 服務
/// <param name="fileName">上傳的檔案名</param>
/// <param name="stream">POST 過來的資料</param>
[WebInvoke(UriTemplate = "UploadString/?fileName={fileName}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
public bool UploadString(string fileName, Stream stream)
// 檔案的服務端儲存路徑
string path = Path.Combine("C:\\", fileName);
try
{
using (StreamReader sr = new StreamReader(stream))
{
// 将 POST 過來的被 Base64 編碼過字元串傳換成 byte[]
byte[] buffer = Convert.FromBase64String(sr.ReadToEnd());
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
// 将檔案寫入到服務端
fs.Write(buffer, 0, buffer.Length);
}
}
return true;
}
catch
return false;
/// 用于示範以流的形式上傳資料的 REST 服務
/// <param name="stream">POST 過來的資料(流的方式)</param>
[WebInvoke(UriTemplate = "UploadStream/?fileName={fileName}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
public bool UploadStream(string fileName, Stream stream)
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
byte[] buffer = new byte[4096];
int count = 0;
// 每 POST 過來 4096 位元組的資料,往服務端寫一次
while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
fs.Write(buffer, 0, count);
}
WebClientUpload.xaml
<UserControl x:Class="Silverlight20.Communication.WebClientUpload"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<StackPanel Margin="5" Width="200">
<TextBox x:Name="lblMsgString" Margin="5" />
<ProgressBar x:Name="progressBarString" Height="20" Margin="5" Minimum="0" Maximum="100" />
<Button x:Name="btnString" Content="上傳檔案(字元串的方式)" Margin="5" Click="btnString_Click" />
</StackPanel>
<TextBox x:Name="lblMsgStream" Margin="5" />
<ProgressBar x:Name="progressBarStream" Height="20" Margin="5" Minimum="0" Maximum="100" />
<Button x:Name="btnStream" Content="上傳檔案(流的方式)" Margin="5" Click="btnStream_Click" />
</StackPanel>
</UserControl>
WebClientUpload.xaml.cs
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.Resources;
using System.ComponentModel;
using System.Windows.Browser;
namespace Silverlight20.Communication
public partial class WebClientUpload : UserControl
// 用于示範以字元串的形式上傳資料
string _urlString = "http://localhost:3036/REST.svc/UploadString/?fileName=";
// 用于示範以流的形式上傳資料
string _urlStream = "http://localhost:3036/REST.svc/UploadStream/?fileName=";
public WebClientUpload()
InitializeComponent();
/// <summary>
/// 示範字元串式上傳
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnString_Click(object sender, RoutedEventArgs e)
string data = "";
/*
* OpenFileDialog - 檔案對話框
* ShowDialog() - 顯示檔案對話框。在檔案對話框中單擊“确定”則傳回true,反之則傳回false
* File - 所選檔案的 FileInfo 對象
*/
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == true)
using (FileStream fs = dialog.File.OpenRead())
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
// 将指定的 byte[] 轉換為字元串(使用Base64編碼)
data = Convert.ToBase64String(buffer);
/*
* WebClient - 将資料發送到指定的 URI,或者從指定的 URI 接收資料的類
* UploadStringCompleted - 上傳資料完畢後(包括取消操作及有錯誤發生時)所觸發的事件
* UploadProgressChanged - 上傳資料過程中所觸發的事件。正在上傳或上傳完全部資料後會觸發
* Headers - 與請求相關的的标頭的 key/value 對集合
* UploadStringAsync(Uri address, string data) - 以字元串的形式上傳資料到指定的 URI。所使用的 HTTP 方法預設為 POST
* Uri address - 接收上傳資料的 URI
* string data - 需要上傳的資料
*/
System.Net.WebClient clientUploadString = new System.Net.WebClient();
clientUploadString.UploadStringCompleted += new UploadStringCompletedEventHandler(clientUploadString_UploadStringCompleted);
clientUploadString.UploadProgressChanged += new UploadProgressChangedEventHandler(clientUploadString_UploadProgressChanged);
Uri uri = new Uri(_urlString + dialog.File.Name, UriKind.Absolute);
clientUploadString.Headers["Content-Type"] = "application/x-www-form-urlencoded";
clientUploadString.UploadStringAsync(uri, data);
void clientUploadString_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
* UploadProgressChangedEventArgs.ProgressPercentage - 上傳完成的百分比
* UploadProgressChangedEventArgs.BytesSent - 目前發送的位元組數
* UploadProgressChangedEventArgs.TotalBytesToSend - 總共需要發送的位元組數
* UploadProgressChangedEventArgs.BytesReceived - 目前接收的位元組數
* UploadProgressChangedEventArgs.TotalBytesToReceive - 總共需要接收的位元組數
* UploadProgressChangedEventArgs.UserState - 使用者辨別
lblMsgString.Text = string.Format("上傳完成的百分比:{0}\r\n目前發送的位元組數:{1}\r\n總共需要發送的位元組數:{2}\r\n目前接收的位元組數:{3}\r\n總共需要接收的位元組數:{4}\r\n",
e.ProgressPercentage.ToString(),
e.BytesSent.ToString(),
e.TotalBytesToSend.ToString(),
e.BytesReceived.ToString(),
e.TotalBytesToReceive.ToString());
progressBarString.Value = (double)e.ProgressPercentage;
void clientUploadString_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
* UploadStringCompletedEventArgs.Error - 該異步操作期間是否發生了錯誤
* UploadStringCompletedEventArgs.Cancelled - 該異步操作是否已被取消
* UploadStringCompletedEventArgs.Result - 服務端傳回的資料(字元串類型)
* UploadStringCompletedEventArgs.UserState - 使用者辨別
if (e.Error != null)
lblMsgString.Text += e.Error.ToString();
return;
if (e.Cancelled != true)
var jsonObject = System.Json.JsonObject.Parse(e.Result);
lblMsgString.Text += string.Format("是否上傳成功:{0}",
(bool)jsonObject);
/// 示範流式上傳
private void btnStream_Click(object sender, RoutedEventArgs e)
FileStream fs = null;
fs = dialog.File.OpenRead();
* OpenWriteCompleted - 在打開用于上傳的流完成時(包括取消操作及有錯誤發生時)所觸發的事件
* WriteStreamClosed - 在寫入資料流的異步操作完成時(包括取消操作及有錯誤發生時)所觸發的事件
* UploadProgressChanged - 上傳資料過程中所觸發的事件。如果調用 OpenWriteAsync() 則不會觸發此事件
* OpenWriteAsync(Uri address, string method, Object userToken) - 打開流以使用指定的方法向指定的 URI 寫入資料
* string method - 所使用的 HTTP 方法(POST 或 GET)
* Object userToken - 需要上傳的資料流
System.Net.WebClient clientUploadStream = new System.Net.WebClient();
clientUploadStream.OpenWriteCompleted += new OpenWriteCompletedEventHandler(clientUploadStream_OpenWriteCompleted);
clientUploadStream.UploadProgressChanged += new UploadProgressChangedEventHandler(clientUploadStream_UploadProgressChanged);
clientUploadStream.WriteStreamClosed += new WriteStreamClosedEventHandler(clientUploadStream_WriteStreamClosed);
Uri uri = new Uri(_urlStream + dialog.File.Name, UriKind.Absolute);
clientUploadStream.Headers["Content-Type"] = "multipart/form-data";
clientUploadStream.OpenWriteAsync(uri, "POST", fs);
void clientUploadStream_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
// 因為是調用 OpenWriteAsync(),是以不會觸發 UploadProgressChanged 事件
progressBarStream.Value = (double)e.ProgressPercentage;
void clientUploadStream_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
System.Net.WebClient client = sender as System.Net.WebClient;
lblMsgStream.Text += e.Error.ToString();
// e.UserState - 需要上傳的流(用戶端流)
Stream clientStream = e.UserState as Stream;
// e.Result - 目标位址的流(服務端流)
Stream serverStream = e.Result;
// clientStream.Read - 将需要上傳的流讀取到指定的位元組數組中
while ((count = clientStream.Read(buffer, 0, buffer.Length)) > 0)
// serverStream.Write - 将指定的位元組數組寫入到目标位址的流
serverStream.Write(buffer, 0, count);
serverStream.Close();
clientStream.Close();
void clientUploadStream_WriteStreamClosed(object sender, WriteStreamClosedEventArgs e)
else
lblMsgStream.Text += "上傳完成";
}
/*
* 其他:
* 1、WebClient 對象一次隻能啟動一個請求。如果在一個請求完成(包括出錯和取消)前,即IsBusy為true時,進行第二個請求,則第二個請求将會抛出 NotSupportedException 類型的異常
* 2、如果 WebClient 對象的 BaseAddress 屬性不為空,則 BaseAddress 與 URI(相對位址) 組合在一起構成絕對 URI
* 3、WebClient 類的 AllowReadStreamBuffering 屬性:是否對從 Internet 資源接收的資料做緩沖處理。預設值為true,将資料緩存在用戶端記憶體中,以便随時被應用程式讀取
*/
OK
<a href="http://down.51cto.com/data/100302" target="_blank">[源碼下載下傳]</a>
本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/343126,如需轉載請自行聯系原作者