使用WCF上传文件

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

{
        [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;

    }{
        [OperationContract(Action = "UploadFile", IsOneWay = true)]
        void UploadFile(FileUploadMessage request);
    }

[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】利用WCF实现上传下载文件服务

    引言     前段时间,用WCF做了一个小项目,其中涉及到文件的上传下载.出于复习巩固的目的,今天简单梳理了一下,整理出来,下面展示如何一步步实现一个上传下载的WCF服务. 服务端 1.首先新建一个名 ...

  2. 【ARM-LInux开发】利用scp 远程上传下载文件/文件夹

    利用scp 远程上传下载文件/文件夹 scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o s ...

  3. 利用scp 远程上传下载文件/文件夹和ssh远程执行命令

    利用scp传输文件 1.从服务器下载文件scp username@servername:/path/filename /tmp/local_destination例如scp codinglog@192 ...

  4. 利用 secureCRT 直接上传下载文件 (sz,rz)

    在window下向linux传送文件的方法. 首先在window中安装SecureCRT,然后在快速连接中建立一个到linux的连接,当然,你要先知道你的系统的ip,在终端中键入ifconfig可以查 ...

  5. linux利用scp远程上传下载文件/文件夹

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度. 当你服务 ...

  6. 利用scp 远程上传下载文件/文件夹

    scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port ...

  7. linux利用sh脚本上传下载文件到ftp服务器

    ####本地的/app/awsm/csv2 to ftp服务器上的/awsm/#### #!/bin/sh export today=`date +%Y-%m-%d` ftp -v -n 10.116 ...

  8. 如何利用京东云的对象存储(OSS)上传下载文件

    作者:刘冀 在公有云厂商里都有对象存储,京东云也不例外,而且也兼容S3的标准因此可以利用相关的工具去上传下载文件,本文主要记录一下利用CloudBerry Explorer for Amazon S3 ...

  9. shell通过ftp实现上传/下载文件

    直接代码,shell文件名为testFtptool.sh: #!/bin/bash ########################################################## ...

随机推荐

  1. 单用户模式破解root密码

  2. python --- 21 MRO C3算法

    一.python2.2之前用的是   经典类的MRO继承 ①深度递归继承     从左到右 ,一条路走到黑 ②广度继承           一层一层的继承 深度继承时   为   R 1 2 3 4 ...

  3. Install jdk on Ubuntu16

    wikiHow to Install Oracle Java JDK on Ubuntu Linux This tutorial will cover the installation of 32-b ...

  4. Flask学习【第8篇】:flask-session组件

    简介 flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多个地方,如 redis:保存数据 ...

  5. SpringBoot Mybatis问题收集

    1.在SpringBoot中打印mybatis中执行的sql 其实在application.properties 文件下,添加一下配置即可: logging.level.org.springframe ...

  6. HDU 5938 Four Operations(乱搞)题解

    题意:把'+', '-', '*' 和'/'按顺序插入任意两数字间隔,使得操作得到后计算后最大. 思路:没想到是个水题,打的时候想得太复杂了.这道题其实只要考虑*和/.显然我们要把a*b/c弄到最小. ...

  7. size_t和unsigned int区别

    size_t和unsigned int有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int.最典型 ...

  8. Vue内置的Component标签用于动态切换组件

    html <div id="app"> <component :is="cut"></component> <butt ...

  9. [quartz] - Cron表达式举例

    Quartz是一个任务调度框架.比如你遇到这样的问题 想每月25号,信用卡自动还款 想每年2月14日自己给当年暗恋女神发一封匿名贺卡 想每隔1小时,备份一下自己的SpringCloud学习笔记到云盘 ...

  10. 【ASP.Net】 web api中的media type

    1. 有什么用? 通常用来标识http请求中的内容的类型用来告诉server端如何解析client端发送的message, 或者标识client希望从server端得到的资源是什么样的类型.又被称为M ...