[Silverlight][C#] 上傳檔案到Server
2012-10-05
這是模擬跟ASP.net 時代一樣的檔案上傳方式, 跟大家分享一下..
這問題我超級常被問到的..
其實做法跟傳統都一樣... 將FileStream傳給一個ashx ,
之後透過ashx將檔案寫入在Server指令目錄中.
一.首先先製作.ashx 我們開一個方案叫做 FileUploadMemo 為Silverlight 專案..
這時候我們在預設的FileUploadMemo.Web 中加入一個upload.ashx
用來服務client 上傳檔案上來...
其中他預設的Code 我們把他改成這樣…
說明我寫在註解之中…
using System; using System.IO; using System.Web; namespace FileUploadMemo.Web { public class upload : IHttpHandler { public void ProcessRequest(HttpContext context) { try { //取得副檔名 string fileextname = context.Request.QueryString["ext"].ToString(); //製作一個新的檔名 string newFilename = Guid.NewGuid().ToString().Replace("-", ""); //儲存路徑 DirectoryInfo FileDir = new DirectoryInfo(System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "source\\"); //如果檔案夾沒有建立則自行建立 if (FileDir.Exists == false) { FileDir.Create(); } using (FileStream fs = File.Create((System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "source\\" + newFilename + fileextname))) { SaveFile(context.Request.InputStream, fs); } } catch (Exception ex) { } } //將收到的stream 寫入檔案 private void SaveFile(Stream stream, FileStream fs) { try { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0) { fs.Write(buffer, 0, bytesRead); } } catch (Exception ex) { //這邊可以放入錯誤的Log } } public bool IsReusable { get { return false; } } } }
其中值得一提的…
因為是範例 所以我設定他
1.上傳時候必須要給已知的副檔名,並且透過get方式 傳ext這參數 進來..
2.他會將檔案寫到source 檔案夾下面
3.如果要控管安全機制,可以在參數中加入token設定一組密碼,不然大家都亂上傳一些怪東西就不好了..
好了之後我們就執行一下…取得服務路徑..之後會用到…
我們就取得執行的路徑…會一片空白是正常的…
二. 接下來就是Silverlight 這一端了..
我們盡量讓程式簡單..
放一個按鈕為button1 使用者點下去之後..
就會選檔->上傳->顯示完成.
XAML Code :
<UserControl x:Class="FileUploadMemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="選擇檔案" Height="23" HorizontalAlignment="Left" Margin="304,110,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" FontSize="14" /> <sdk:Label Height="28" HorizontalAlignment="Left" Margin="35,110,0,0" Name="label1" VerticalAlignment="Top" Width="243" Content="請選擇上傳檔案,選擇完後即上傳" FontSize="14" /> </Grid> </UserControl>
接下來我們來看C# Code
記得要先using
using System.IO; using System.Net;
C# Code (註解裡面有說明):
private void button1_Click(object sender, System.Windows.RoutedEventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Multiselect = false; //這邊可以設定過副檔名過濾器 dlg.Filter = "jpeg檔 (*.jpg)|*.jpg"; bool? retval = dlg.ShowDialog(); if (retval != null && retval == true) { UploadFile(dlg.File.Name, dlg.File.OpenRead()); } } //上傳檔案 private void UploadFile(string fileName, Stream data) { //下面敘述網址必須輸入服務的ashx 網址 UriBuilder ub = new UriBuilder("http://localhost:1209/upload.ashx"); //取得並將副檔名取出傳送 ub.Query = string.Format("ext={0}", Path.GetExtension(fileName)); WebClient c = new WebClient(); c.OpenWriteCompleted += (sender, e) => { PushData(data, e.Result); e.Result.Close(); data.Close(); MessageBox.Show("上傳完畢"); }; c.OpenWriteAsync(ub.Uri); } private void PushData(Stream input, Stream output) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0) { output.Write(buffer, 0, bytesRead); } }
請注意上傳後 … 因為source 是程式建立出來的..
所以Visual Studio 會熊熊看不到…
要記得打開顯示全部檔案..
打開上傳檔案後…
完成…
請注意:
這邊是把案例簡化到很簡單,其實關於IO存取,很多小細節需要注意..
像是 權限控管,檔案位置規劃,重複寫檔問題,上傳進度等候時間,檔案大小限制。
這都是需要注意的,這不是本文重點,所以這些都是需要注意的 ..^^
讚一下:
檔案下載:
標籤:
C#
,
Silverlight
-- Yesterday I wrote down the code. I bet I could be your hero. I am a mighty little programmer. 如果這篇文章有幫助到您,簡單留個言,或是幫我按個讚,讓我有寫下去的動力...