WCF – MetaData
WCF的metadata描述了用戶端如何同服務進行互動。通過metadata,我們可以利用一些工具產生proxy代碼,比如SvcUtil.exe,用戶端編程基本上是基於這些proxy的
服務有兩種方案發行就緒自己的中繼資料。一種是基於HTTP-GET協議提供中繼資料;另一種則為中繼資料交換方式,它往往使用一個專門的終結點,稱之為中繼資料交換終結點。中繼資料交換終結點與其它終結點相似,仍然包含了地址、綁定與契約,但是使用的服務契約為WCF提供的介面IMetadataExchange。
實際上,這兩種發布中繼資料的方式代表了它使用了兩種不同的標準協議,前者為HTTP/GET請求,後者為WS-MetadataExchange(MEX)。在WCF,以MetadataExchangeClientMode枚舉類型表示這兩種中繼資料交換模式:
public enum MetadataExchangeClientMode{ MetadataExchange, HttpGet}
1. HTTP-GET
起用了這種方式的metadata發布,用戶端可以通過瀏覽器察看並確認中繼資料。同前面幾篇文章介紹的一樣,啟用方法也是2種:編成和配置。
配置中繼資料發佈是通過添加ServiceBehavior來實現的,例子如下:
<system.serviceModel> <services> <service name="MyNamespace.MyService" behaviroConfiguration="MEXGET"> <endpoint contract = "MyNamespace.IMyService" binding = "wsHttpBinding" address = "http://localhost:8000/MyService" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MEXGET"> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors></system.serviceModel>
編程方式:
ServiceHost host = new ServiceHost(typeof(MyService));ServiceMetadataBehavior metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();if(metadataBehavior == null){ metadataBehavior = new ServiceMetadataBehavior(); metadataBehavior.HttpGetEnabled = true; host.Description.Behaviors.Add(metadataBehavior);}Binding wsHttpBinding = new WSHttpBinding();host.AddServiceEndpoint(typeof(IMyService), wsHttpBinding, new Uri("http://localhost:8086/MyService/"));host.Open();... host.Close();
2. Metadata-Exchange
這種方式是通過定義特定的endpoint的方式來發布中繼資料,這種endpoint被稱作中繼資料終結點或者MEX終結點。WCF為MEX終結點的ABC分別給出了各自的定義。
- A - 類似於普通的endpoint地址。
- B - 基於http, https, tcp和icp協議的binding。例如,mexTcpBinding, mexNamePipeBinding, mexHttpBinding….
- C - IMetadataExchange介面。其實現由WCF自動提供。
以下是一個配置Mex endpoint的例子:
<system.serviceModel> <services> <service name="MyNamespace.MyService" behaviroConfiguration="MEX"> <endpoint contract = "MyNamespace.IMyService" binding = "wsHttpBinding" address = "http://localhost:8000/MyService" /> <endpoint contract = "IMetadataExchange" binding = "mexHttpBinding" address = "http://localhost:8000/MEX" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MEX"> <serviceMetadata/> </behavior> </serviceBehaviors> </behaviors></system.serviceModel>
同樣可以通過編程的方式來啟動mex endpoint:
BindingElement bindingElement = new TcpTransportBindingElement();CustomBinding binding = new CustomBinding(bindingElement);Uri tcpBaseAddress = new Uri("net.tcp://localhost:9000");ServiceHost host = new ServiceHost(typeof(MyService), tcpBaseAddress);if(metadataBehavior == null){ metadataBehavior = new ServiceMetadataBehavior(); host.Description.Behaviors.Add(metadataBehavior);}host.AddServiceEndpoint(typeof(IMetadataExchange), binding, "MEX");host.Open();... host.Close();