傳統 ASMX Web Service 上傳檔案效率低、無法傳輸大檔案。雖可用 WSE MTOM 改善,但 WCF 內建支援 Stream 傳輸大型二進制資料,架構更完善。
BasicHttpBinding、NetTcpBinding、NetNamedPipeBinding 支援 StreamStream、MemoryStream)Message Body) **只能包含單一 Stream**,不可混入其他資料TransferMode 與 MaxReceivedMessageSize 限制因 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 唯一成員為 Streampublic 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 緩衝區分塊寫入。
<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>
| 屬性 | 值 | 說明 |
|---|---|---|
transferMode | Streamed | 啟用串流傳輸 (預設 Buffered) |
messageEncoding | Mtom | MTOM 編碼,二進制附件傳輸,效率優於 Text/XML |
maxReceivedMessageSize | 9223372036854775807 (Int64.MaxValue) | 移除預設 4MB 限制,允許超大檔案 |
sendTimeout | 00:10:00 | 大檔案上傳需較長逾時 |
<system.web>
<httpRuntime maxRequestLength="2097151" /> <!-- 2GB,單位 KB -->
</system.web>
預設 ASP.NET 限制 4MB,需同步調整。
**客戶端繫結組態必須與服務端完全一致** (transferMode、messageEncoding、maxReceivedMessageSize)。
建立 Console 或 Web 專案加入服務參考,呼叫 UploadFile 傳送大檔案驗證。完整原始碼請參考文章附件。