在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,接口文件的代码如下:

[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配置:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="FileTransferServicesBinding" maxReceivedMessageSize="9223372036854775807"
          messageEncoding="Mtom" transferMode="Streamed" sendTimeout="00:10:00" />
          </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="UploadWcfService.UpLoadServiceBehavior"
        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 includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

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

这样WCFService就完成了,新建一个Console项目或者Web项目测试一下。要注意的
是Client端的配置必须要和服务端一样,实例程序在这里下载

使用WCF上传文件的更多相关文章

  1. wcf 上传文件报413,404和发布错误

    上传文件错误: 其实要修改所有的服务,不管是服务端还是客户端,Binding那边增加一个没有设置名字的默认配置就OK了:  <binding   closeTimeout="00:10 ...

  2. IOS And WCF 上传文件

    IOS And WCF Story 研究IOS上传到WCF图片的小功能,WCF实现服务端的文件上传的例子很多,单独实现IOS发送图片的例子也很多,但是两个结合起来的就很少了. 可以通过base64来上 ...

  3. WCF上传、下载、删除文件

    关键代码: --上传的stream处理,转为bytep[] private void Parse(Stream stream, Encoding encoding) { this.Success = ...

  4. WebService支持多平台上传文件的实现

    WebService支持多平台上传文件的实现   要使用网站上传文件,在ASP.NET的范畴,我基本上能想到的有两类,一类是通过HTTP POST请求获得文件信息,另外一类是通过WebService或 ...

  5. IE8/9 JQuery.Ajax 上传文件无效

    IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...

  6. 三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader

    发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"up ...

  7. asp.net mvc 上传文件

    转至:http://www.cnblogs.com/fonour/p/ajaxFileUpload.html 0.下载 http://files.cnblogs.com/files/fonour/aj ...

  8. app端上传文件至服务器后台,web端上传文件存储到服务器

    1.android前端发送服务器请求 在spring-mvc.xml 将过滤屏蔽(如果不屏蔽 ,文件流为空) <!-- <bean id="multipartResolver&q ...

  9. .net FTP上传文件

    FTP上传文件代码实现: private void UploadFileByWebClient() { WebClient webClient = new WebClient(); webClient ...

随机推荐

  1. sklearn中模型抽取

    特征抽取sklearn.feature_extraction 模块提供了从原始数据如文本,图像等众抽取能够被机器学习算法直接处理的特征向量. 1.特征抽取方法之 Loading Features fr ...

  2. C++之赋值、比较、逻辑运算符

    赋值运算符 **作用:**用于将表达式的值赋给变量 赋值运算符包括以下几个符号: int main() { //赋值运算符 // = ; a = ; cout << "a = & ...

  3. js只能输入数字和小数点

    1.文本框只能输入数字代码(小数点也不能输入)<input onkeyup="this.value=this.value.replace(/\D/g,'')" onafter ...

  4. 针对Java集合类的小总结

    Java集合类包位于java.util下,有很多常用的数据结构:数组.链表.队列.栈.哈希表等等.了解不同的集合类的特性在开发过程中是比较重要的,感谢@兰亭风雨的专栏分析,这里我也根据自己的理解做轻度 ...

  5. C++ vector操作--往列表中添加或更新内容

    有个列表,往里面添加内容,如果对象已存在,只更新其属性,否则添加新一项. #include <iostream> #include <string> #include < ...

  6. 2018-8-10-VisualStduio-打断点调试和不打断点调试有什么区别

    title author date CreateTime categories VisualStduio 打断点调试和不打断点调试有什么区别 lindexi 2018-08-10 19:16:52 + ...

  7. sql (8) AVG

    SQL avg 语法SELECT AVG(column_name) FROM table_name新建表:StudentS S_id Grade Name phone1 98 小明 1234562 9 ...

  8. node---处理post请求

    //nodejs 处理post请求 // 异步 const http =require('http') const server=http.createServer((req,res)=>{ i ...

  9. Bugs Integrated, Inc.

    Bugs Integrated, Inc. 给出一个\(n\times m\)的矩形网格图,给出其中K个障碍物的位置,求其中最多能摆的\(2\times 3\)的矩形的个数,\(n\leq 150,m ...

  10. 在VMware中创建一个新的虚拟机 ,安装Linux4.X系统 ,之后在此基础上安装openfiler(网络存储管理实用程序)

    到此为止虚拟机的前期设置准备好了 下面来为此虚拟机添加iso镜像 (这个是在http://www.openfiler.com/community/download  openfiler官网上面下载的) ...