Silverlight WCF 上传实现
上一篇中提高Silverlight實現文件上傳的一些思路,說實在的,在寫哪篇文章之前并沒有親身試驗過,雖說是思路,但是萬一有偏差還是有點冒險。
?
經過自己測試后,得意證明,Silverlight 利用 WCF實現上傳確實是如此的簡單方便,邏輯上也非常的順暢。
?
廢話不說,看過前一篇文章后對Silverlight 利用 WCF實現上傳大概有概念上的理解,下面直接就是代碼部分了。
?
此代碼只是先了文件上傳,界面沒怎么做就兩個按鈕,文件名和上傳消息通知都直接顯示在按鈕上,這是為了讓代碼看上去簡單,更容易理解,見諒。
?
實現:
首先,創建一個ASP.NET項目,然后再該項目中創建一個用于啟動于Silverlight的WCF服務 ,也就是一個SVC文件以及.CS代碼文件。我取名為Upload.svc,代碼如下
?
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
?
namespace WebApp4SL
{
??? [ServiceContract(Namespace = "Zeta")]
??? [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
??? public class UpLoad
??? {
??????? [OperationContract]
??????? public string Upload(byte[] bytes,string filename)
??????? {
??????????? System.IO.FileStream fs = new System.IO.FileStream(System.Web.HttpContext.Current.Server.MapPath("UploadFile")+"/"+filename,System.IO.FileMode.Create);
?
??????????? fs.Write(bytes,0,bytes.Length);
?
??????????? fs.Flush();
?
??????????? fs.Close();
???????????
??????????? return "成功!";
??????? }
?
??? }
}
?
?
?這里成功與否當然應該加入更多判斷,例如文件是否有重名,或者是否是可支持的類型,我的示例中都沒有判斷,實際項目中都應該加上,還有就是錯誤處理 TRY。
?
服務器端就此完成,當然,你還得在ASP.NET項目下新建一個目錄用于存放上傳來的文件,我命名為UploadFile
?
?
接下來就是客戶端Silverlight的代碼了,首先創建一個Silverlight項目,然后引用剛才我們創建的WCF服務。接下來寫Page.xaml及其代碼,Page.xaml.cs 如下
?
?
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.Xml;
using System.IO;
using System.Text;
?
namespace SilverlightTest
{
??? public partial class Page : UserControl
??? {
?
?
?? ?????byte[] bytes;
??????? string filename;
??????? public Page()
??????? {
??????????? InitializeComponent();
???????????
??????? }
?
??????? private void UserControl_Loaded(object sender, RoutedEventArgs e)
??????? {
??????? }
?
??????? private void UserControl_KeyDown(object sender, KeyEventArgs e)
??????? {
??????? }
?
??????? private void openfile_Click(object sender, RoutedEventArgs e)
??????? {
??????????? OpenFileDialog op = new OpenFileDialog();
???????????
??????????? if (op.ShowDialog()==true)
??????????? {
??????????????? FileStream fs = op.File.OpenRead();
?
??????????????? bytes = new byte[fs.Length];
?
??????????????? fs.Read(bytes,0,bytes.Length);
?
??????????????? openfile.Content =op.File.Name;
??????????????? filename = op.File.Name;
?? ?????????}
??????? }
?
??????? private void upload_Click(object sender, RoutedEventArgs e)
??????? {
??????????? if (bytes != null)
??????????? {
??????????????? WebApp.UpLoadClient uc = new SilverlightTest.WebApp.UpLoadClient();
?
??????????????? uc.UploadCompleted += new EventHandler<SilverlightTest.WebApp.UploadCompletedEventArgs>(uc_UploadCompleted);
?
??????????????? uc.UploadAsync(bytes,filename);
??????????? }
??????? }
?
??????? void uc_UploadCompleted(object sender, SilverlightTest.WebApp.UploadCompletedEventArgs e)
??????? {
??????????? openfile.Content = e.Result;
??????? }
??? }
}
?
?
很簡單,可以說是簡陋,但是很能說明問題。
?
最后就是更簡單的Page.xaml文件
?
?
<UserControl x:Class="SilverlightTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?? ?xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?? ?Width="400" Height="300" xmlns:SilverlightTest="clr-namespace:SilverlightTest" Loaded="UserControl_Loaded" KeyDown="UserControl_KeyDown">
????
???? <StackPanel x:Name="sp">
??????? <Button x:Name="openfile" Content="瀏覽" Click="openfile_Click"></Button>
??????? <Button x:Name="upload" Content="上傳" Click="upload_Click"></Button>
??? </StackPanel>
??
?
</UserControl>
?
至此,完成了Silverlight的上傳功能。可以看到,Silverlight在客戶端獲取文件流,寫到了一個緩沖塊,然后直接將緩沖塊作為WCF服務方法的參數,請求執行WCF服務的方法,這個緩沖塊就被傳遞到了服務器,并在服務器上的WCF服務后臺代碼被處理,處理效果就是將這個緩沖塊寫入到一個文件流保存起來。
?
很簡單吧,而且很直觀,與以往寫入到HTTP請求流,再從請求流里操作簡單了一些,但是你也許會說,這樣的方法并不比ASP.NET里那個上傳控件簡單多少啊。但是直接用上傳控件會遇到的兩個問題很讓人棘手,第一就是文件的體積問題,上傳大體積會消耗很多時間,也占用較大服務器內存,隨之而來的就是HTTP超時問題,另一個就是進度問題,HTTP上傳是無法顯示進度的,當然AJAX的分塊可以解決,但是如果我們用SILVERLIGHT,就更簡單了,將客戶端文件流分塊寫入到緩沖塊,然后再一次次分別去調用WCF的服務方法,保存成分塊的小文件,最后,執行一次合并方法,將文件合并后保存,我的這個例里沒有實現這個功能,但是改進下很容易,分塊后,做進度就不是什么問題了吧,因為有WCF方法的異步回調時間,一切都是那么簡單。
?
另外,如果在沒有使用分塊上傳的情況下單個上傳文件比較大,或者分塊上傳單塊過大,有可能出現 NOTFOUND異常,為什么,那是你的WCF配置限制引起的,可以在 WEBCONFI文件里進行修改。添加類似以下配置代碼
<basicHttpBinding>
<binding name="LargeBuffer" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="UTF-8" sendTimeout="00:05:10" receiveTimeout="00:05:10" openTimeout="00:05:10" closeTimeout="00:05:10">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
?
如果不知道怎么配置,可以在VS2008里右鍵點解WEB.CONFIG 選擇 編輯WCF配置 進入配置界面。
轉載于:https://www.cnblogs.com/ZetaChow/archive/2009/04/26/2237352.html
總結
以上是生活随笔為你收集整理的Silverlight WCF 上传实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据表现层文件命名参考
- 下一篇: asp.net跨页面传值收集