天天看點

化零為整WCF(8) - 消息處理(使用流資料傳輸檔案)

<a href="http://webabcd.blog.51cto.com/1787395/343999" target="_blank">[索引頁]</a>

化零為整WCF(8) - 消息處理(使用流資料傳輸檔案)

介紹

WCF(Windows Communication Foundation) - 消息處理:使用流資料傳輸檔案,減少記憶體開銷。

示例

1、服務

IStreamed.cs

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Text; 

using System.ServiceModel; 

using System.IO; 

namespace WCF.ServiceLib.Message 

        /// &lt;summary&gt; 

        /// 消息契約(定義與 SOAP 消息相對應的強類型類) 

        /// &lt;/summary&gt; 

        [MessageContract] 

        public class FileWrapper 

        { 

                /// &lt;summary&gt; 

                /// 指定資料成員為 SOAP 消息頭 

                /// &lt;/summary&gt; 

                [MessageHeader] 

                public string FilePath; 

                /// 指定将成員序列化為 SOAP 正文中的元素 

                [MessageBodyMember] 

                public Stream FileData; 

        } 

        /// IStreamed接口 

        [ServiceContract] 

        public interface IStreamed 

                /// 上傳檔案 

                /// &lt;remarks&gt; 

                /// 1、支援資料流傳輸的綁定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 

                /// 2、流資料類型必須是可序列化的 Stream 或 MemoryStream 

                // /3、傳遞時消息體(Message Body)中不能包含其他資料,即參數中隻能有一個System.ServiceModel.MessageBodyMember 

                /// &lt;/remarks&gt; 

                /// &lt;param name="fileWrapper"&gt;WCF.ServiceLib.Message.FileWrapper&lt;/param&gt; 

                [OperationContract] 

                void UploadFile(FileWrapper fileWrapper); 

}

Streamed.cs

        /// IStreamed類 

        public class Streamed : IStreamed 

                public void UploadFile(FileWrapper fileWrapper) 

                { 

                        var sourceStream = fileWrapper.FileData; 

                        var targetStream = new FileStream(fileWrapper.FilePath, 

                                FileMode.Create, 

                                FileAccess.Write, 

                                FileShare.None); 

                        var buffer = new byte[4096]; 

                        var count = 0; 

                        while ((count = sourceStream.Read(buffer, 0, buffer.Length)) &gt; 0) 

                        { 

                                targetStream.Write(buffer, 0, count); 

                        } 

                        targetStream.Close(); 

                        sourceStream.Close(); 

                } 

2、宿主

using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.Streamed))) 

        host.Open(); 

        Console.WriteLine("服務已啟動(WCF.ServiceLib.Message.Streamed)"); 

        Console.WriteLine("按&lt;ENTER&gt;停止服務"); 

        Console.ReadLine(); 

App.config

&lt;?xml version="1.0" encoding="utf-8" ?&gt; 

&lt;configuration&gt; 

    &lt;system.serviceModel&gt; 

        &lt;services&gt; 

            &lt;!--name - 提供服務的類名--&gt; 

            &lt;!--behaviorConfiguration - 指定相關的行為配置--&gt; 

            &lt;service name="WCF.ServiceLib.Message.Streamed" behaviorConfiguration="MessageBehavior"&gt; 

                &lt;!--address - 服務位址--&gt; 

                &lt;!--binding - 通信方式--&gt; 

                &lt;!--contract - 服務契約--&gt; 

                &lt;!--bindingConfiguration - 指定相關的綁定配置--&gt; 

                &lt;endpoint address="Message/Streamed" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IStreamed" bindingConfiguration="StreamedBindingConfiguration" /&gt; 

                &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /&gt; 

                &lt;host&gt; 

                    &lt;baseAddresses&gt; 

                        &lt;add baseAddress="http://localhost:12345/Message/Streamed/"/&gt; 

                        &lt;add baseAddress="net.tcp://localhost:54321/"/&gt; 

                    &lt;/baseAddresses&gt; 

                &lt;/host&gt; 

            &lt;/service&gt; 

        &lt;/services&gt; 

        &lt;behaviors&gt; 

            &lt;serviceBehaviors&gt; 

                &lt;behavior name="MessageBehavior"&gt; 

                    &lt;!--httpGetEnabled - 使用get方式提供服務--&gt; 

                    &lt;serviceMetadata httpGetEnabled="true" /&gt; 

                    &lt;serviceDebug includeExceptionDetailInFaults="true"/&gt; 

                &lt;/behavior&gt; 

            &lt;/serviceBehaviors&gt; 

        &lt;/behaviors&gt; 

        &lt;bindings&gt; 

            &lt;netTcpBinding&gt; 

                    &lt;!--transferMode - 訓示通道是使用流處理模式還是緩沖模式來傳輸請求和響應消息--&gt; 

                    &lt;!--maxReceivedMessageSize - 在采用此綁定配置的通道上可接收的最大消息大小(機關:位元組)--&gt; 

                    &lt;!--receiveTimeout - 在傳輸引發異常之前可用于完成讀取操作的時間間隔--&gt; 

                    &lt;binding name="StreamedBindingConfiguration" transferMode="Streamed" maxReceivedMessageSize="1073741824" receiveTimeout="00:10:00" /&gt; 

            &lt;/netTcpBinding&gt; 

        &lt;/bindings&gt; 

    &lt;/system.serviceModel&gt; 

&lt;/configuration&gt;

3、用戶端

using System.Windows.Forms; 

namespace Client2.Message 

        /// 示範Message.Streamed的類 

        public class Streamed 

                /// 流資料上傳檔案 

                /// &lt;param name="source"&gt;源檔案位址&lt;/param&gt; 

                /// &lt;param name="destination"&gt;目标路徑&lt;/param&gt; 

                public void HelloStreamed(string source, string destination) 

                        try 

                                var proxy = new MessageSvc.Streamed.StreamedClient(); 

                                var sr = new System.IO.FileStream( 

                                        source, System.IO.FileMode.Open); 

                                proxy.UploadFile(destination + Path.GetFileName(source), sr); 

                                sr.Close(); 

                                proxy.Close(); 

                                MessageBox.Show("上傳成功"); 

                        catch (Exception ex) 

                                MessageBox.Show(ex.ToString()); 

        &lt;client&gt; 

            &lt;!--address - 服務位址--&gt; 

            &lt;!--binding - 通信方式--&gt; 

            &lt;!--contract - 服務契約--&gt; 

            &lt;endpoint address="net.tcp://localhost:54321/Message/Streamed" binding="netTcpBinding" contract="MessageSvc.Streamed.IStreamed" bindingConfiguration="StreamedBindingConfiguration" /&gt; 

        &lt;/client&gt; 

                    &lt;!--sendTimeout - 在傳輸引發異常之前可用于完成寫入操作的時間間隔--&gt; 

                    &lt;binding name="StreamedBindingConfiguration" transferMode="Streamed" sendTimeout="00:10:00" /&gt; 

運作結果:

上傳檔案後提示上傳成功

OK

<a href="http://down.51cto.com/data/100781" target="_blank">[源碼下載下傳]</a>

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/344131,如需轉載請自行聯系原作者