WCF編碼器正確創建方式解讀
在應用WCF之前,我們需要創建一個編碼器來幫組我們的程序開發。那么如何才能正確的實現WCF編碼器的創建呢?首先,我們需要創建一個定制的MessageEncoderFactory,它能創建我們的定制的編碼器對象,它需要:#t#
一個被覆蓋的編碼器對象
一個被覆蓋的消息版本
包含一個從CustomMessageEncoder工廠創建的名為CustomEncoderFactory的樣本類。我們需要將該編碼器標記為一個單獨的CustomMessageEncoder工廠對象。
為了創建一個CustomEncoderFactory實例,需要傳入兩個新的東西:一個EncodeMode枚舉值以及一個EnableCompression變量:
EncodeMode是一個可根據配置值動態改變編碼格式,并且無需知道任何特殊的WCF編碼器的深入知識就可以編寫壓縮/解壓縮邏輯的枚舉值。它支持各種壓縮類型,包括None、Deflate、Gzip,同時,我們還可以添加更多定制的壓縮編碼器格式:
- /// < summary>
- /// Compression Encoder formats. Add custom encoders such as
- /// ICSharpLib, 7z, rar
- /// < /summary>
- public enum CompressionEncoder
- {
- None,
- Deflate,
- GZip
- }
EnableCompression是一個布爾開關值,通過它可以啟用或者禁用壓縮處理。
接下來,我們需要創建一個CustomEncoder,以實現抽象類MessageEncoder,具體代碼如清單2所示。清單2的示例代碼實現了IsDataCompressed方法,用以確定數據是否已經壓縮。對于Gzip,可以使用“幻碼”值來確定數據是否經過壓縮處理。
就像前面提到的那樣,這個定制的WCF編碼器的編碼過程是在ReadMessage和WriteMessage方法中進行的。所以,我們還需要覆蓋ContentType屬性來交付不同的內容類型。枚舉類型的CompressionEncoder變量值決定了運行時的內容類型。
然后,我們需要創建一個CustomMessageEncodingBinding元素,以便規定可配置的定制屬性,在本例中它包含EnableCompression、CompressionEncoder 和捆綁元素。
***,我們需要創建一個CustomMessageEncodingElement元素,它派生自BindingElementExtensionElement類。
從配置文件讀取這些值之后,CreateBindingElement方法充當一個入口點,并將這些值轉換成定制的捆綁元素的適當的屬性。
我們需要注意的事項如下所示:CreateBindingElement方法,它充當一個入口點。
注意,我們可以通過配置修改捆綁元素的messageversion屬性,但是為簡單起見,我們在此不對此加以討論。
ApplyConfiguration方法,它使我們可以顯式指定屬性。
ReaderQuotas,它用來給CustomMesssageEncodingBindingElement指定屬性。
值ReaderQuotas.MaxArrayLength可以控制請求大小。因為這個例子使用定制的捆綁,所以需要將其設為捆綁元素。
***,需要實現CustomBindingElement的配置部分。對于客戶端,配置看上去是這樣的:
- < system.serviceModel>
- < extensions>
- < bindingElementExtensions>
- < add name="customMessageEncoding" type="
- Infrastructure.CustomEncoder.CustomMessageEncodingElement, assemblyname" />
- < /bindingElementExtensions>
- < /extensions>
- < bindings>
- < customBinding>
- < binding name="myBinding">
- < customMessageEncoding innerMessageEncoding=
- "textMessageEncoding" enableCompression="false"
- compressionEncode="gzip">
- < readerQuotas maxArrayLength="62914560" >< /readerQuotas>
- < /customMessageEncoding >
- < httpTransport maxBufferSize="62914560"
- maxReceivedMessageSize="62914560"
- authenticationScheme="Anonymous"
- proxyAuthenticationScheme="Anonymous"
- useDefaultWebProxy="true"
- />
- < /binding>
- < /customBinding>
- < /bindings>
- < client>
- < endpoint address="http://127.0.0.1/mywcf.services/service1.svc"
- binding="customBinding" bindingConfiguration="myBinding"
- contract="IService" name="Service1">
- < /endpoint>
- < /client>
- < /system.serviceModel>
上面創建的定制的捆綁使用新的CustomMessageEncoding。請求通常不需要壓縮,因為它們通常很小;事實上,壓縮它們反而會增加請求的尺寸。因此,以上顯示的客戶端配置文件了enableCompression ="false"的設置。服務器配置看起來象這樣:
- < system.serviceModel>
- < extensions>
- < bindingElementExtensions>
- < add name="customMessageEncoding" type="
- Infrastructure.CustomEncoder.CustomMessageEncodingElement, assemblyname" />
- < /bindingElementExtensions>
- < /extensions>
- < bindings>
- < customBinding>
- < binding name="myBinding">
- < customMessageEncoding
- innerMessageEncoding="textMessageEncoding"
- enableCompression="true"
- compressionEncode="gzip">
- < readerQuotas
- maxArrayLength="62914560" >
- < /readerQuotas>
- < /customMessageEncoding >
- < httpTransport maxBufferSize="62914560"
- maxReceivedMessageSize="62914560"
- authenticationScheme="Anonymous"
- proxyAuthenticationScheme="Anonymous"
- useDefaultWebProxy="true" />
- < /binding>
- < /customBinding>
- < bindings>
- < services>
- < service behaviorConfiguration="Host.Behavior"
- name="Host.Service">
- endpoint address=""
- binding="customBinding"
- bindingConfiguration="myBinding"
- contract="ServiceContracts.IService" />
- < endpoint address="mex" binding="mexHttpBinding"
- contract="IMetadataExchange" />
- < /service>
- < /services>
- < /system.serviceModel>
通過閱讀本文,您會發現向我們的WCF編碼器中添加定制的編碼不僅簡單,而且還是透明的。我們的示例代碼不僅包含了文中描述的class屬性的詳盡的源代碼,而且還提供了所需的配置章節。