WCF上传文件方法总结
来源:互联网 发布:淘宝卖家怎么删除宝贝 编辑:程序博客网 时间:2024/05/16 03:20
在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,接口文件的代码如下:
定义FileUploadMessage类的目的是因为第三个限制,要不然文件名和存放路径就没办法传递给WCF了,根据第二个限制,文件数据是用System.IO.Stream来传递的
接口方法只有一个,就是上传文件,注意方法参数是FileUploadMessage
接口实现类文件的代码如下:
WebService来上传文件存在的问题是效率不高,而且不能传输大数据量的文件,当然你可以用Wse中的MTOM来传输大文件,有了WCF就好多了,通过使用WCF传递Stream对象来传递大数据文件,但有一些限制:
1、只有 BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。
2、 流数据类型必须是可序列化的 Stream 或 MemoryStream。
3、 传递时消息体(Message Body)中不能包含其他数据。
4、TransferMode的限制和MaxReceivedMessageSize的限制等。
下面具体实现:新建一个WCFService,接口文件的代码如下:
[ServiceContract] public interface IUpLoadService { [OperationContract(Action = "UploadFile", IsOneWay = true)] void UploadFile(FileUploadMessage request); } [MessageContract] public class FileUploadMessage { [MessageHeader(MustUnderstand = true)] public string SavePath; [MessageHeader(MustUnderstand = true)] public string FileName; [MessageBodyMember(Order = 1)] public Stream FileData; }
定义FileUploadMessage类的目的是因为第三个限制,要不然文件名和存放路径就没办法传递给WCF了,根据第二个限制,文件数据是用System.IO.Stream来传递的
接口方法只有一个,就是上传文件,注意方法参数是FileUploadMessage
接口实现类文件的代码如下:
public class UpLoadService : IUpLoadService { public void UploadFile(FileUploadMessage request) { string uploadFolder = @"C:\kkk\"; string savaPath = request.SavePath; string dateString = DateTime.Now.ToShortDateString() + @"\"; string fileName = request.FileName; Stream sourceStream = request.FileData; FileStream targetStream = null; if (!sourceStream.CanRead) { throw new Exception("数据流不可读!"); } if (savaPath == null) savaPath = @"Photo\"; if (!savaPath.EndsWith("\\")) savaPath += "\\"; uploadFolder = uploadFolder + savaPath + dateString; if (!Directory.Exists(uploadFolder)) { Directory.CreateDirectory(uploadFolder); } string filePath = Path.Combine(uploadFolder, fileName); using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) { //read from the input stream in 4K chunks //and save to output stream const int bufferLen = 4096; byte[] buffer = new byte[bufferLen]; int count = 0; while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0) { targetStream.Write(buffer, 0, count); } targetStream.Close(); sourceStream.Close(); } } }
实现的功能是到指定目录下按照日期进行目录划分,然后以传过来的文件名保存文件。
这篇文章最主要的地方就是下面的Web.Config配置:一定要按这个配置来
配置要遵循上面的第一条和第四条限制,因为默认.net只能传4M的文件,所以要在
<System.Web>配置节下面加上<httpRuntime maxRequestLength="2097151" />
这样WCFService就完成了,新建一个Console项目或者Web项目测试一下。要注意的是Client端的配置必须要和服务端一样。
这篇文章最主要的地方就是下面的Web.Config配置:一定要按这个配置来
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="FileTransferServicesBinding" maxReceivedMessageSize="9223372036854775807" messageEncoding="Mtom" transferMode="Streamed" sendTimeout="00:10:00" /> </basicHttpBinding> </bindings> <services> <service behaviorC name="UploadWcfService.UpLoadService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="UploadWcfService.IUpLoadService"> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="UploadWcfService.UpLoadServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExcepti /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
配置要遵循上面的第一条和第四条限制,因为默认.net只能传4M的文件,所以要在
<System.Web>配置节下面加上<httpRuntime maxRequestLength="2097151" />
这样WCFService就完成了,新建一个Console项目或者Web项目测试一下。要注意的是Client端的配置必须要和服务端一样。
以上是从网上找的方法,但是你试过之后会发现,在Console项目中直接添加服务引用生成代理类是可以的,用的是同步方法,会直接在方法中将FileUploadMessage的三个成员变量作为参数进行传递,但是我的项目是Silverlight,默认生成的代理只有基于事件的异步方法,会看到生成的UploadFileAsnyc方法只有一个byte[]类型的参数 fileData,根本就没有其他两个参数……百般无奈,我又改回不用MessageContract和Stream,直接用byte[]二进制数据进行传输……方法差不多。
- WCF上传文件方法总结
- WCF 文件上传
- WCF上传大文件
- 使用WCF上传文件
- 用WCF上传文件
- WCF 学习总结7 -- 流模式(Streaming)实现文件上传
- Silverlight中用WCF实现文件快速上传(一、基本方法)
- Silverlight中用WCF实现文件快速上传(一、基本方法)
- Thinkphp 文件上传方法总结
- IOS And WCF 上传文件
- Web文件上传方法总结大全
- Web文件上传方法总结大全
- wcf大文件上传配置详解
- WCF实现文件的上传与下载
- flex上传文件到wcf restful
- WCF利用Stream上传大文件
- WCF实现的文件上传和下载
- 利用WCF上传,下载,删除服务器文件
- 类加载器ClassLoader概述
- 利用JavaScript从UIWebView获取、修改、提交网页内数据的方法
- 时隔三年
- Croc Champ 2013 - Round 2 Div. 2 D
- UESTC 1823 In Galgame We Trust 模拟
- WCF上传文件方法总结
- UVA 378 Intersecting Lines POJ 1249【直线位置情况简单判定】
- Matlab调用动态链接库
- PHP 折半查找(二分查找) 递归与非递归法
- AIX6.1上单实例oracle 11.2.0.3.0 升级到 11.2.0.3.4
- 提取ipa里面的资源图片
- 杭电2034
- what is programming?
- TrustZone技术简介