首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

使用 WCF 實作大檔案上傳:Stream 傳輸、MTOM 編碼與組態完整指南

     編輯:關於.NET

背景與 Web Service 限制

傳統 ASMX Web Service 上傳檔案效率低、無法傳輸大檔案。雖可用 WSE MTOM 改善,但 WCF 內建支援 Stream 傳輸大型二進制資料,架構更完善。

WCF Stream 傳輸限制

  1. 僅 BasicHttpBinding、NetTcpBinding、NetNamedPipeBinding 支援 Stream
  2. Stream 型別必須可序列化 (Stream、MemoryStream)
  3. 訊息本文 (Message Body) **只能包含單一 Stream**,不可混入其他資料
  4. 受 TransferMode 與 MaxReceivedMessageSize 限制

服務合約設計:MessageContract 解決 Body 限制

因 Body 僅能含一個 Stream,檔名、路徑等中繼資料需放入 MessageHeader:

[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;
}
  • IsOneWay = true:單向操作,客戶端不等待回應
  • MessageHeader:SOAP Header 傳遞中繼資料
  • MessageBodyMember:SOAP Body 唯一成員為 Stream

服務實作:分塊寫入檔案

public class UpLoadService : IUpLoadService
{
    public void UploadFile(FileUploadMessage request)
    {
        string uploadRoot = @"C:\kkk\";
        string savePath = request.SavePath ?? @"Photo\";
        string datePath = DateTime.Now.ToShortDateString() + @"\";
        string fileName = request.FileName;
        Stream source = request.FileData;

        if (!source.CanRead) throw new Exception("資料流不可讀!");

        if (!savePath.EndsWith(@"\")) savePath += @"\";
        string fullDir = Path.Combine(uploadRoot, savePath, datePath);

        if (!Directory.Exists(fullDir)) Directory.CreateDirectory(fullDir);

        string filePath = Path.Combine(fullDir, fileName);

        using (var target = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            const int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            int count;
            while ((count = source.Read(buffer, 0, bufferSize)) > 0)
            {
                target.Write(buffer, 0, count);
            }
        }
        source.Close();
    }
}

功能:依日期建立子目錄,以原始檔名儲存,4KB 緩衝區分塊寫入。

關鍵組態:Web.config / App.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 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>

關鍵繫結設定解析

屬性值說明
transferModeStreamed啟用串流傳輸 (預設 Buffered)
messageEncodingMtomMTOM 編碼,二進制附件傳輸,效率優於 Text/XML
maxReceivedMessageSize9223372036854775807 (Int64.MaxValue)移除預設 4MB 限制,允許超大檔案
sendTimeout00:10:00大檔案上傳需較長逾時

ASP.NET 相容模式額外設定

<system.web>
  <httpRuntime maxRequestLength="2097151" /> <!-- 2GB,單位 KB -->
</system.web>

預設 ASP.NET 限制 4MB,需同步調整。

客戶端組態

**客戶端繫結組態必須與服務端完全一致** (transferMode、messageEncoding、maxReceivedMessageSize)。

測試驗證

建立 Console 或 Web 專案加入服務參考,呼叫 UploadFile 傳送大檔案驗證。完整原始碼請參考文章附件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved