Silverlight中用WCF实现文件快速上传(一、基本方法)
2010-04-23 08:22
381 查看
在Silverlight中可能通过服务上传文件。通过服务上传文件可以比较方便地实现异步上传、分块上传、进度显示等等功能。因此,“Silverlight + 服务”组合可以实现比较强大类似于C/S模式中的那种上传功能。下面详细说明实现步骤。
1. 创建Silverlight应用程序。
这个是基本能力,不会的先找资料学习一下吧。
假定创建的解决方案为:UploadFiles。默认情况下存在两个项目:UploadFiles和UploadFiles.Web。
2. 添加WCF服务。
在UploadFiles.Web项目中添加WCF服务:右键→添加→新建项→选“启用 Silverlight 功能的 WCF 服务”,如果VS是英文的则为“Silverlight-enabled WCF Service”。
3. WCF服务的代码:
4. Silverlight中的上传执行代码
在MainPage.xaml中添加一个执行上传的按钮,后台执行代码如下:
辅助类:
5. 上传数据尺寸配置
默认情况下,WCF只允许最大16KB的数据块上传。按此尺寸,实测上传速度很慢。如果要修改尺寸,则要修改Web.config文件。
注意:是修改UploadFiles.Web中的Web.config,而不是UploadFiles中的ServiceReferences.ClientConfig。最开始我曾以为是修改后者,结果被困了好久,汗颜!
网上有好多文章讲修改参数的,但无一指明是修改.Web项目中的Web.config,让我困惑了好久,最后在一个英文网页中找到的答案……。
修改后的内容如下:
修改的结果是允许最大2MB的数据块上传。Sunpire网友(参见参考文献2)提到的要增加24KB冗余的问题,我在实测中没有遇到。即:Sunpire网友的文章中提到<customBinding>要设置2MB+24KB,才能上传2MB数据的情况我没有遇到。我实际设置2MB就能上传2MB数据。当然,我没有象Sunpire网友那样去做那么多测试,只做了1MB和2MB的测试。
6. 总结
按照上述方法,可以实现各种文件快速上传。小文件上传几乎是瞬间的事,大文件也很快。
缺点:上传时会一次性的把整个文件读入内存。进一步的解决方案是边读边上传。
参考文献:
[1]agile 的《Silverlight 3 中使用WCF上传文件 (简单进度条展示)》:/content/1759877.html
[2]Sunpire 的《Silverlight+WCF文件上传,含分段大小调节(WCF 16KB配置)、压缩Buffer调节、速度指示、批量等》:http://www.soaspx.com/dotnet/silverlight/silverlight_20100321_3357.html
1. 创建Silverlight应用程序。
这个是基本能力,不会的先找资料学习一下吧。
假定创建的解决方案为:UploadFiles。默认情况下存在两个项目:UploadFiles和UploadFiles.Web。
2. 添加WCF服务。
在UploadFiles.Web项目中添加WCF服务:右键→添加→新建项→选“启用 Silverlight 功能的 WCF 服务”,如果VS是英文的则为“Silverlight-enabled WCF Service”。
3. WCF服务的代码:
namespace UploadFiles.Web { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service1 { [OperationContract] public void DoWork() { // 在此处添加操作实现 return; } // 在此处添加更多操作并使用 [OperationContract] 标记它们 [OperationContract] public void ActionUpload(string fileName, byte[] fileData, bool isAppend) { //文件上传所在目录 //可以按日期、文件类型或混合建立相应的文件目录,以便使用 string uploadFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/upload"); //目录不存在则新建 if (!System.IO.Directory.Exists(uploadFolder)) { System.IO.Directory.CreateDirectory(uploadFolder); } //文件读写模式 //如果参数为真则表示续传,以追回模式写文件 System.IO.FileMode fileMode = isAppend ? System.IO.FileMode.Append : System.IO.FileMode.Create; //写入文件 using (System.IO.FileStream fs = new System.IO.FileStream(uploadFolder + @"/" + fileName, fileMode, System.IO.FileAccess.Write)) { fs.Write(fileData, 0, fileData.Length); } } } }
4. Silverlight中的上传执行代码
在MainPage.xaml中添加一个执行上传的按钮,后台执行代码如下:
private void Button_Click(object sender, RoutedEventArgs e) { //选择本地文件对话框 OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "(*.*)|*.*"; //单选 openFileDialog.Multiselect = false; if (openFileDialog.ShowDialog() == true) { //所选上传文件信息 FileInfo fileInfo = openFileDialog.File; //上传文件信息 UploadFileInfo uploadFileInfo = new UploadFileInfo(); uploadFileInfo.Name = fileInfo.Name; //文件内容 Stream stream = fileInfo.OpenRead(); uploadFileInfo.Size = (int)(stream.Length / 1024); uploadFileInfo.Data = new List<byte[]>(); //读取指定大小的文件流内容到uploadFile.Data以便上传 int len; long rest; while (stream.Position > -1 && stream.Position < stream.Length) { rest = stream.Length - stream.Position; //len = (rest >= 16384) ? 16384 : (int)rest; //WCF默认配置参数最大只允许16KB len = (rest >= 2097152) ? 2097152 : (int)rest; //2MB byte[] fileData = new byte[len]; stream.Read(fileData, 0, len); uploadFileInfo.Data.Add(fileData); } stream.Close(); localService.Service1Client wcfService = new TestUploadFile_WCF.localService.Service1Client(); wcfService.ActionUploadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(wcfService_ActionUploadCompleted); wcfService.ActionUploadAsync(uploadFileInfo.Name, uploadFileInfo.Data[0], false, uploadFileInfo); } } void wcfService_ActionUploadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { if (e.Error == null) { UploadFileInfo uploadFileInfo = e.UserState as UploadFileInfo; uploadFileInfo.Status += uploadFileInfo.Data[0].Length / 1024; uploadFileInfo.Data.RemoveAt(0); if (uploadFileInfo.Data.Count == 0) { btnUploadFile.Content = "Uploaded"; MessageBox.Show("文件上传成功。"); } else { (sender as localService.Service1Client).ActionUploadAsync(uploadFileInfo.Name, uploadFileInfo.Data[0], true, uploadFileInfo); btnUploadFile.Content = uploadFileInfo.Status.ToString() + "/" + uploadFileInfo.Size.ToString() + "KB Uploaded."; } } }
辅助类:
public class UploadFileInfo { //文件名 public string Name { get; set; } //文件大小 public int Size { get; set; } //上传状态 public int Status { get; set; } //文件流 public List<byte[]> Data { get; set; } }
5. 上传数据尺寸配置
默认情况下,WCF只允许最大16KB的数据块上传。按此尺寸,实测上传速度很慢。如果要修改尺寸,则要修改Web.config文件。
注意:是修改UploadFiles.Web中的Web.config,而不是UploadFiles中的ServiceReferences.ClientConfig。最开始我曾以为是修改后者,结果被困了好久,汗颜!
网上有好多文章讲修改参数的,但无一指明是修改.Web项目中的Web.config,让我困惑了好久,最后在一个英文网页中找到的答案……。
修改后的内容如下:
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="UploadFiles.Web.Service1Behavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <customBinding> <binding name="customBinding0"> <binaryMessageEncoding> <readerQuotas maxArrayLength="2097152"/><!--2MB--> </binaryMessageEncoding> <httpTransport maxReceivedMessageSize="2147483647"/> </binding> </customBinding> </bindings> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> <services> <service behaviorConfiguration="UploadFiles.Web.Service1Behavior" name="UploadFiles.Web.Service1"> <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="UploadFiles.Web.Service1"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> </system.serviceModel>
修改的结果是允许最大2MB的数据块上传。Sunpire网友(参见参考文献2)提到的要增加24KB冗余的问题,我在实测中没有遇到。即:Sunpire网友的文章中提到<customBinding>要设置2MB+24KB,才能上传2MB数据的情况我没有遇到。我实际设置2MB就能上传2MB数据。当然,我没有象Sunpire网友那样去做那么多测试,只做了1MB和2MB的测试。
6. 总结
按照上述方法,可以实现各种文件快速上传。小文件上传几乎是瞬间的事,大文件也很快。
缺点:上传时会一次性的把整个文件读入内存。进一步的解决方案是边读边上传。
参考文献:
[1]agile 的《Silverlight 3 中使用WCF上传文件 (简单进度条展示)》:/content/1759877.html
[2]Sunpire 的《Silverlight+WCF文件上传,含分段大小调节(WCF 16KB配置)、压缩Buffer调节、速度指示、批量等》:http://www.soaspx.com/dotnet/silverlight/silverlight_20100321_3357.html
相关文章推荐
- Silverlight中用WCF实现文件快速上传(一、基本方法)
- Silverlight中用WCF实现文件快速上传(一、基本方法)(转载)
- Silverlight中用WCF实现文件快速上传(一、基本方法)
- Silverlight中用WCF实现文件快速上传(二、改进)
- Silverlight中用WCF实现文件快速上传(二、改进)
- JSP实现快速上传文件的方法
- Silverlight文件上传下载实现方法(下载保存)
- JSP实现快速上传文件的方法
- PHP三种方法实现多文件上传
- PHP 文件上传进度条的两种实现方法的代码
- ASP.NET上传文件的三种基本方法
- JavaBean实现多个文件上传的两种方法
- 使用简单的wcf文件实现上传,下载文件到服务器
- Ajax简单实现文件异步上传的多种方法
- jquery.MultiFile实现的多文件上传,只把待上传的文件名以列表展示在客户端并不上传的方法
- yii使用activeFileField控件实现上传文件与图片的方法
- python通过shutil实现快速文件复制的方法
- 文件上传的各种实现方法比较
- struts2+jsp实现文件上传的方法
- iOS 断点上传文件的实现方法