WCF編碼器正確創(chuàng)建方式解讀
在應(yīng)用WCF之前,我們需要?jiǎng)?chuàng)建一個(gè)編碼器來(lái)幫組我們的程序開(kāi)發(fā)。那么如何才能正確的實(shí)現(xiàn)WCF編碼器的創(chuàng)建呢?首先,我們需要?jiǎng)?chuàng)建一個(gè)定制的MessageEncoderFactory,它能創(chuàng)建我們的定制的編碼器對(duì)象,它需要:#t#
一個(gè)被覆蓋的編碼器對(duì)象
一個(gè)被覆蓋的消息版本
包含一個(gè)從CustomMessageEncoder工廠創(chuàng)建的名為CustomEncoderFactory的樣本類。我們需要將該編碼器標(biāo)記為一個(gè)單獨(dú)的CustomMessageEncoder工廠對(duì)象。
為了創(chuàng)建一個(gè)CustomEncoderFactory實(shí)例,需要傳入兩個(gè)新的東西:一個(gè)EncodeMode枚舉值以及一個(gè)EnableCompression變量:
EncodeMode是一個(gè)可根據(jù)配置值動(dòng)態(tài)改變編碼格式,并且無(wú)需知道任何特殊的WCF編碼器的深入知識(shí)就可以編寫(xiě)壓縮/解壓縮邏輯的枚舉值。它支持各種壓縮類型,包括None、Deflate、Gzip,同時(shí),我們還可以添加更多定制的壓縮編碼器格式:
- /// < summary>
 - /// Compression Encoder formats. Add custom encoders such as
 - /// ICSharpLib, 7z, rar
 - /// < /summary>
 - public enum CompressionEncoder
 - {
 - None,
 - Deflate,
 - GZip
 - }
 
EnableCompression是一個(gè)布爾開(kāi)關(guān)值,通過(guò)它可以啟用或者禁用壓縮處理。
接下來(lái),我們需要?jiǎng)?chuàng)建一個(gè)CustomEncoder,以實(shí)現(xiàn)抽象類MessageEncoder,具體代碼如清單2所示。清單2的示例代碼實(shí)現(xiàn)了IsDataCompressed方法,用以確定數(shù)據(jù)是否已經(jīng)壓縮。對(duì)于Gzip,可以使用“幻碼”值來(lái)確定數(shù)據(jù)是否經(jīng)過(guò)壓縮處理。
就像前面提到的那樣,這個(gè)定制的WCF編碼器的編碼過(guò)程是在ReadMessage和WriteMessage方法中進(jìn)行的。所以,我們還需要覆蓋ContentType屬性來(lái)交付不同的內(nèi)容類型。枚舉類型的CompressionEncoder變量值決定了運(yùn)行時(shí)的內(nèi)容類型。
然后,我們需要?jiǎng)?chuàng)建一個(gè)CustomMessageEncodingBinding元素,以便規(guī)定可配置的定制屬性,在本例中它包含EnableCompression、CompressionEncoder 和捆綁元素。
***,我們需要?jiǎng)?chuàng)建一個(gè)CustomMessageEncodingElement元素,它派生自BindingElementExtensionElement類。
 
從配置文件讀取這些值之后,CreateBindingElement方法充當(dāng)一個(gè)入口點(diǎn),并將這些值轉(zhuǎn)換成定制的捆綁元素的適當(dāng)?shù)膶傩浴?/p>
我們需要注意的事項(xiàng)如下所示:CreateBindingElement方法,它充當(dāng)一個(gè)入口點(diǎn)。
注意,我們可以通過(guò)配置修改捆綁元素的messageversion屬性,但是為簡(jiǎn)單起見(jiàn),我們?cè)诖瞬粚?duì)此加以討論。
ApplyConfiguration方法,它使我們可以顯式指定屬性。
ReaderQuotas,它用來(lái)給CustomMesssageEncodingBindingElement指定屬性。
值ReaderQuotas.MaxArrayLength可以控制請(qǐng)求大小。因?yàn)檫@個(gè)例子使用定制的捆綁,所以需要將其設(shè)為捆綁元素。
***,需要實(shí)現(xiàn)CustomBindingElement的配置部分。對(duì)于客戶端,配置看上去是這樣的:
- < 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>
 
上面創(chuàng)建的定制的捆綁使用新的CustomMessageEncoding。請(qǐng)求通常不需要壓縮,因?yàn)樗鼈兺ǔ:苄?事實(shí)上,壓縮它們反而會(huì)增加請(qǐng)求的尺寸。因此,以上顯示的客戶端配置文件了enableCompression ="false"的設(shè)置。服務(wù)器配置看起來(lái)象這樣:
- < 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>
 
通過(guò)閱讀本文,您會(huì)發(fā)現(xiàn)向我們的WCF編碼器中添加定制的編碼不僅簡(jiǎn)單,而且還是透明的。我們的示例代碼不僅包含了文中描述的class屬性的詳盡的源代碼,而且還提供了所需的配置章節(jié)。















 
 
 






 
 
 
 