Silverlight中用WCF实现文件快速上传(一、基本方法)
来源:互联网 发布:js 隐藏元素 编辑:程序博客网 时间:2024/05/02 00:37
在Silverlight中可能通过服务上传文件。通过服务上传文件可以比较方便地实现异步上传、分块上传、进度显示等等功能。因此,“Silverlight + 服务”组合可以实现比较强大类似于C/S模式中的那种上传功能。下面详细说明实现步骤。
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上传文件 (简单进度条展示)》:http://my.oschina.net/agile/blog/2130
[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 上传实现
- WCF上传文件方法总结
- Silverlight+WCF上传文件(文件分段,百分比进度条显示)
- WCF实现文件的上传与下载
- WCF实现的文件上传和下载
- Java中用Socket实现文件上传
- 在struts2中用fileupload实现文件上传
- iPHone 中用 NSURLRequest 实现文件上传
- 在struts2中用fileupload实现文件上传
- 使用silverlight实现多文件上传
- django 快速实现文件上传
- django 快速实现文件上传
- django 快速实现文件上传
- Silverlight+WCF实现聊天功能
- Servlet实现基本文件上传
- 调试过程中出现以下问题.\layout\activity_main.out.xml:1: error: Error parsing XML: no element found
- maskView动画
- linux c获取系统启动时间
- Step into Kotlin - 11 - 类
- 三维数组用法
- Silverlight中用WCF实现文件快速上传(一、基本方法)
- 用45点阐明报告你水对人体的重要性
- 黑马程序员-oc基础-oc中之集合NSArray,NSMutableArray
- quick3x_Lua中的继承
- Median of Two Sorted Arrays
- Android管理篇
- 共享打印机时,出现"无法访问,你可能没有权限使用网络资源“
- 实木办公众具选购细致啦!
- 属鸡男士的最佳婚配