使用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. 前后台分离开发--文件上传与下载,cookie,session

    一.前后台分离开发的概念 ''' 1. 前台页面运行在前台服务器上,负责页面的渲染(静态文件的加载)与转跳 2. 后台代码运行在后台服务器上,负责数据的处理(提供数据请求的接口) ''' #如果没有前 ...

  2. SVM学习笔记2-拉格朗日对偶

    下面我们抛开1中的问题.介绍拉格朗日对偶.这一篇中的东西都是一些结论,没有证明. 假设我们有这样的问题:$min_{w}$ $f(w)$,使得满足:(1)$g_{i}(w)\leq 0,1\leq i ...

  3. 第一次参加acm区域赛

    什么,这周天就要去参加acm焦作赛,简直不敢相信.从大一暑假七月份中旬到今天十一月23日,加入acm将近四个多月的时间,如今到了检验自己的时候了.aaaaaaaaaa.乌拉,必胜.打印个模板,在跑个步 ...

  4. dijkstra最短路

    感觉自己太懒了,以后每天更博客激励自己吧. //时间复杂度O(n*n)的最短路算法 //首先需要设置一个访问数组v[maxn],一个数组d[maxn], memset(v,,sizeof(v)); ; ...

  5. Eclipse使用maven命令安装第三方jar包

    使用原因: 使用maven时,有些第三方jar包是不能从maven远程仓库中下载得到,因此导致在pom.xml中添加jar包依赖时会怎么添加都会报错(Missing artifact ojdbc:oj ...

  6. 2199: [Usaco2011 Jan]奶牛议会 2-sat

    链接 https://www.luogu.org/problemnew/show/P3007 https://www.lydsy.com/JudgeOnline/problem.php?id=2199 ...

  7. 【拼接属性查询方式】MySql某一列属性值为拼接时的查询方式

    数据库中某一列的值为 使用IN查询是无法查询到数据的,只能查询到IN(2)或者IN(2,3)  查询结果: , style_id) 正确方式:使用FIND_IN_SET函数 , style_id) , ...

  8. BZOJ 3622 已经没有什么好怕的了

    扯淡 看到题目想到二项式反演 然后忘了给求阶乘的时候取模,调了一晚上 真令人窒息 思路 二项式反演 首先二项式反演还有另一种形式(不会证) 设\(G_i\)为有至少i个的方案数量,\(F_i\)为恰好 ...

  9. [jsp & thymeleaf] - jsp和thymeleaf的共存解析

    做项目时因为有些老jsp还需要测试用到,所以之前的thymeleaf也需要保持,配置如下: https://github.com/deadzq/jsp-thymeleaf 等空余时间在做详解吧!

  10. Nuget 打包 for .Net Standart project

    Create .NET Standard packages with Visual Studio 2015 Publishing packages nuge.exe 放在项目目录中 nuget spe ...