WCF上傳文件解決方案剖析
WCF是一個.NET Framework 3.5的重要組成部分,它的書籍應(yīng)用給開發(fā)人員帶來了非常大的幫助。我們今天就可以先從WCF上傳文件的相關(guān)步驟,來分析一下這一工具的簡單實現(xiàn)方法,幫助我們理解應(yīng)用。#t#
在WCF沒出現(xiàn)之前,我一直使用用WebService來上傳文件,我不知道別人為什么要這么做,因為我們的文件服務(wù)器和網(wǎng)站后臺和網(wǎng)站前臺都不在同一個機(jī)器,操作人員覺得用FTP傳文件太麻煩,我就做一個專門用來上傳文件的WebService,把這個WebService部署在文件服務(wù)器上,然后在網(wǎng)站后臺調(diào)用這個WebService,把網(wǎng)站后臺頁面上傳上來的文件轉(zhuǎn)化為字節(jié)流傳給WebService,然后WebService把這個字節(jié)流保存文件到一個只允許靜態(tài)頁面的網(wǎng)站(靜態(tài)網(wǎng)站可以防止一些腳本木馬)。
WebService來上傳文件存在的問題是效率不高,而且不能傳輸大數(shù)據(jù)量的文件,當(dāng)然你可以用Wse中的MTOM來傳輸大文件,有了WCF就好多了,通過使用WCF傳遞Stream對象來傳遞大數(shù)據(jù)文件,但有一些限制:
1、只有 BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持傳送流數(shù)據(jù)。
2、 流數(shù)據(jù)類型必須是可序列化的 Stream 或 MemoryStream。
3、 傳遞時消息體(Message Body)中不能包含其他數(shù)據(jù)。
4、TransferMode的限制和MaxReceivedMessageSize的限制等。
下面具體實現(xiàn):新建一個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了,根據(jù)第二個限制,文件數(shù)據(jù)是用System.IO.Stream來傳遞的接口方法只有一個,就是WCF上傳文件,注意方法參數(shù)是FileUploadMessage
接口實現(xiàn)類文件的代碼如下:
- 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("數(shù)據(jù)流不可讀!");
 - }
 - if (savaPath == null) savaPath = @"Photo\";
 - if (!savaPath.EndsWith("\\")) savaPath += "\\";
 - uploadFolderuploadFolder = 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();
 - }
 - }
 - }
 
實現(xiàn)的功能是到指定目錄下按照日期進(jìn)行目錄劃分,然后以傳過來的文件名保存文件。
這篇WCF上傳文件的文章最主要的地方就是下面的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>
 
配置要遵循上面的***條和第四條限制,因為默認(rèn).net只能傳4M的文件,所以要在< System.Web>配置節(jié)下面加上< httpRuntimemaxRequestLength="2097151" />
以上就是對WCF上傳文件的相關(guān)介紹。















 
 
 
 
 
 
 