WebClient思路及功能實現
實現思路:通過新建一個“一般處理程序”WebClientUpLoadStreamHandler.ashx配合完成,
Silverlight打開文件,獲取文件流,webclient調用openwrite方法,請求服務器,打開一個可以寫進流InputStream。
當該可寫進流可用的時候,相應openwrite異步方法的一個回調事件,在該事件中將文件流寫進到HTTP的可寫進流。服務器端接收到輸進流後寫進到文件流保存。
服務端使用ASHX一般處理程序來作爲接受頁。
本程序中添加“一般處理程序”及其用法介紹請單擊此處,關於一般處理程序的詳細理論介紹請參考http://www.cnblogs.com/JimmyZhang/archive/2007/09/15/894124.html
上傳功能實現
一.選擇本地圖片並指定上傳處理上傳的一般處理程序
/// <summary>
/// 上傳事件通過對話框來選擇上傳文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog()==true)
{
fileinfo = openFileDialog.File;
if (fileinfo!=null)
{
WebClient webclient = new WebClient();
string uploadFileName = fileinfo.Name.ToString();
Uri upTargetUri = new Uri(String.Format ("http://localhost:"+HtmlPage.Document.DocumentUri.Port+"/WebClientUpLoadStreamHandler.ashx?fileName={0}", uploadFileName), UriKind.Absolute); //指定上傳處理程序
webclient.OpenWriteCompleted += new OpenWriteCompletedEventHandler (webclient_OpenWriteCompleted);
//webclient.Headers["Content-Type"] = "multipart/from-data";
webclient.OpenWriteAsync(upTargetUri, "POST", fileinfo.OpenRead());
webclient.WriteStreamClosed += new WriteStreamClosedEventHandler(webclient_WriteStreamClosed);
}
else
{
MessageBox.Show("請選擇想要上傳的圖片!!!");
}
}
}
void webclient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
//將圖片數據流發送到服務器上 e.UserState即爲需要上傳的客戶端的流
Stream clientStream = e.UserState as Stream;
Stream serverStream = e.Result;
byte[] buffer = new byte[4096];
int readcount = 0;
//將需要上傳的流讀取到指定的字節數組中
while ((readcount = clientStream.Read(buffer,0,buffer.Length))>0)
{
//將指定的字節數組寫入到目標地址的流
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);
}
else
{
System.Windows.Browser.HtmlPage.Window.Alert("圖片上傳成功!!!");
c.GetFileListAsync();//這裏是使用了WCF服務返回一下服務端的文件列表,共下載時選擇
}
}
二.服務端獲得上傳流,並保存文件
服務端使用了一般處理程序來配合完成,如何添加一般處理程序請點擊此處
public void ProcessRequest(HttpContext context)
{
string fileNamestr = context.Request.QueryString["fileName"];
Stream sr = context.Request.InputStream;//從客戶端獲得傳入到服務端的文件流
try
{
byte[] buffer = new byte[4096];
int bytestRead = 0;
//將當前數據流寫入服務器端指定文件夾下
string targetPath = context.Server.MapPath("UploadFiles/"+fileNamestr);
using (FileStream fs = File.Create(targetPath, 4096))
{/
//將當前流讀入到字節數組中
while ((bytestRead = sr.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, bytestRead);
}
}
context.Response.ContentType = "text/plain";
context.Response.Write("上傳成功");
}
catch (Exception e)
{
context.Response.ContentType = "text/plain";
context.Response.Write("上傳失敗,錯誤信息:" + e.Message);
}
finally { sr.Dispose(); }
}
下載功能實現
在客戶端直接調用WebClient的自帶方法和事件即可完成下載功能
private void buttonDownload_Click(object sender, RoutedEventArgs e)
{
if (listBox1.SelectedItems.Count<0)
{
MessageBox.Show("請選擇要下載的下載文件");
}
else if (listBox1.SelectedItems.Count>1)
{
MessageBox.Show("暫不提供批量下載");
}
else
{
string imgUrl = "http://localhost:" + HtmlPage.Document.DocumentUri.Port + "/UploadFiles/" + listBox1.SelectedItem.ToString();
Uri endpoint = new Uri(imgUrl);
WebClient client = new WebClient();
//調用WebClient自身事件
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
//調用自身的Read方法完成下載
client.OpenReadAsync(endpoint);
}
}