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的樣本類(lèi)。我們需要將該編碼器標(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ě)壓縮/解壓縮邏輯的枚舉值。它支持各種壓縮類(lèi)型,包括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)抽象類(lèi)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)容類(lèi)型。枚舉類(lèi)型的CompressionEncoder變量值決定了運(yùn)行時(shí)的內(nèi)容類(lèi)型。
然后,我們需要?jiǎng)?chuàng)建一個(gè)CustomMessageEncodingBinding元素,以便規(guī)定可配置的定制屬性,在本例中它包含EnableCompression、CompressionEncoder 和捆綁元素。
***,我們需要?jiǎng)?chuàng)建一個(gè)CustomMessageEncodingElement元素,它派生自BindingElementExtensionElement類(lèi)。
從配置文件讀取這些值之后,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ì)于客戶(hù)端,配置看上去是這樣的:
- < 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)求的尺寸。因此,以上顯示的客戶(hù)端配置文件了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é)。