程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 使用WCF上傳文件

使用WCF上傳文件

編輯:關於.NET

在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端的配置必須要和服務端一樣

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved