WCF上传文件解决方案剖析
创始人
2024-06-23 06:01:21
0次

WCF是一个.NET Framework 3.5的重要组成部分,它的书籍应用给开发人员带来了非常大的帮助。我们今天就可以先从WCF上传文件的相关步骤,来分析一下这一工具的简单实现方法,帮助我们理解应用。#t#

在WCF没出现之前,我一直使用用WebService来上传文件,我不知道别人为什么要这么做,因为我们的文件服务器和网站后台和网站前台都不在同一个机器,操作人员觉得用FTP传文件太麻烦,我就做一个专门用来上传文件的WebService,把这个WebService部署在文件服务器上,然后在网站后台调用这个WebService,把网站后台页面上传上来的文件转化为字节流传给WebService,然后WebService把这个字节流保存文件到一个只允许静态页面的网站(静态网站可以防止一些脚本木马)。

WebService来上传文件存在的问题是效率不高,而且不能传输大数据量的文件,当然你可以用Wse中的MTOM来传输大文件,有了WCF就好多了,通过使用WCF传递Stream对象来传递大数据文件,但有一些限制:

1、只有 BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。

2、 流数据类型必须是可序列化的 Stream 或 MemoryStream。

3、 传递时消息体(Message Body)中不能包含其他数据。

4、TransferMode的限制和MaxReceivedMessageSize的限制等。

下面具体实现:新建一个WCFService,接口文件的代码如下:

  1. [ServiceContract]  
  2. public interface IUpLoadService  
  3. {  
  4. [OperationContract(Action = "UploadFile", IsOneWay = true)]  
  5. void UploadFile(FileUploadMessage request);  
  6. }  
  7. [MessageContract]  
  8. public class FileUploadMessage  
  9. {  
  10. [MessageHeader(MustUnderstand = true)]  
  11. public string SavePath;  
  12. [MessageHeader(MustUnderstand = true)]  
  13. public string FileName;  
  14. [MessageBodyMember(Order = 1)]  
  15. public Stream FileData;  
  16. } 

 

定义FileUploadMessage类的目的是因为第三个限制,要不然文件名和存放路径就没办法传递给WCF了,根据第二个限制,文件数据是用System.IO.Stream来传递的接口方法只有一个,就是WCF上传文件,注意方法参数是FileUploadMessage

接口实现类文件的代码如下:

  1. public class UpLoadService : IUpLoadService  
  2. {  
  3. public void UploadFile(FileUploadMessage request)  
  4. {  
  5. string uploadFolder = @"C:\kkk\";  
  6. string savaPath = request.SavePath;  
  7. string dateString = DateTime.Now.ToShortDateString() + @"\";  
  8. string fileName = request.FileName;  
  9. Stream sourceStream = request.FileData;  
  10. FileStream targetStream = null;  
  11. if (!sourceStream.CanRead)  
  12. {  
  13. throw new Exception("数据流不可读!");  
  14. }  
  15. if (savaPath == null) savaPath = @"Photo\";  
  16. if (!savaPath.EndsWith("\\")) savaPath += "\\";  
  17. uploadFolderuploadFolder = uploadFolder + savaPath + dateString;  
  18. if (!Directory.Exists(uploadFolder))  
  19. {  
  20. Directory.CreateDirectory(uploadFolder);  
  21. }  
  22. string filePath = Path.Combine(uploadFolder, fileName);  
  23. using (targetStream = new FileStream(filePath, FileMode.Create, 
    FileAccess.Write, FileShare.None))  
  24. {  
  25. //read from the input stream in 4K chunks  
  26. //and save to output stream  
  27. const int bufferLen = 4096;  
  28. byte[] buffer = new byte[bufferLen];  
  29. int count = 0;  
  30. while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)  
  31. {  
  32. targetStream.Write(buffer, 0, count);  
  33. }  
  34. targetStream.Close();  
  35. sourceStream.Close();  
  36. }  
  37. }  
  38. } 

 

实现的功能是到指定目录下按照日期进行目录划分,然后以传过来的文件名保存文件。

这篇WCF上传文件的文章最主要的地方就是下面的Web.Config配置:

 

 

 

  1. < system.serviceModel> 
  2. < bindings> 
  3. < basicHttpBinding> 
  4. < binding name="FileTransferServicesBinding" 
    maxReceivedMessageSize="9223372036854775807" 
  5. messageEncoding="Mtom" transferMode="Streamed" sendTimeout="00:10:00" /> 
  6. < /basicHttpBinding> 
  7. < /bindings> 
  8. < services> 
  9. < service behaviorConfiguration="UploadWcfService.UpLoadServiceBehavior" 
  10. name="UploadWcfService.UpLoadService"> 
  11. < endpoint address="" binding="basicHttpBinding" bindingConfiguration=
    "FileTransferServicesBinding" contract="UploadWcfService.IUpLoadService"> 
  12. < /endpoint> 
  13. < endpoint address="mex" binding="mexHttpBinding" 
    contract="IMetadataExchange" /> 
  14. < /service> 
  15. < /services> 
  16. < behaviors> 
  17. < serviceBehaviors> 
  18. < behavior name="UploadWcfService.UpLoadServiceBehavior"> 
  19. < serviceMetadata httpGetEnabled="true" /> 
  20. < serviceDebug includeExceptionDetailInFaults="false" /> 
  21. < /behavior> 
  22. < /serviceBehaviors> 
  23. < /behaviors> 
  24. < /system.serviceModel> 

 

 

配置要遵循上面的***条和第四条限制,因为默认.net只能传4M的文件,所以要在< System.Web>配置节下面加上< httpRuntimemaxRequestLength="2097151" />

以上就是对WCF上传文件的相关介绍。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...