程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WCF技術剖析之二十八:自己動手獲取元數據

WCF技術剖析之二十八:自己動手獲取元數據

編輯:關於.NET

元數據的發布方式決定了元數據的獲取行為,WCF服務元數據架構體系通過ServiceMetadataBehavior實現了基於WS-MEX和HTTP-GET的元數據發布,針對這兩種不同的協議,元數據獲取的實現方式也是不同的。我們首先來實現基於WS-MEX的元數據獲取方式。

本文配套源碼:http://www.bianceng.net/dotnet/201212/655.htm

一、 基於WS-MEX的元數據獲取

ServiceMetadataBehavior通過創建MEX終結點實現了基於WS-MEX的元數據的發布,從《如何將一個服務發布成WSDL》系列文章的介紹我們知道:元數據的發布實際上可以看成是在服務端寄宿一個元數據提供服務,我們通過服務調用的形式獲取元數據。

由於MEX終結點與一般意義上的終結點並沒有本質的不同,我們只需要創建服務元數據發布方相匹配的終結點,相目標地址發送期望的請求消息,即可通過回復消息的形式獲取元數據信息。現在以我們熟悉的計算服務為例,在服務寄宿的時候通過以下的配置為該服務添加一個MEX終結點,采用的MEX綁定和地址分別問:mexHttpBinding和http://127.0.0.1:9999/calculatorservice/mex。

   1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <system.serviceModel>
4: <services>
5: <service name="Artech.MetataRetrieval.Services.CalculatorService" behaviorConfiguration="mexBehavior">
6: <endpoint address=" http://127.0.0.1:9999/calculatorservice" binding="ws2007HttpBinding" contract="Artech.MetataRetrieval.Services.ICalculator"/>
7: <endpoint address="http://127.0.0.1:9999/calculatorservice/mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
8: </service>
9: </services>
10: <behaviors>
11: <serviceBehaviors>
12: <behavior name="mexBehavior">
13: <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:3721/calculatorservice/metadata"/>
14: </behavior>
15: </serviceBehaviors>
16: </behaviors>
17: </system.serviceModel>
18: </configuration>

下面的代碼展現了客戶端獲取元數據的程序,這和一般的服務調用並無二致。首先通過指定相應的綁定(MetadataExchangeBindings.CreateMexHttpBinding())和地址(元數據的目標地址:http://127.0.0.1:9999/calculatorservice/mex)創建ChannelFactory<TChannel>對象(由於MEX終結點契約類型為IMetadataExchange,這裡的TChannel類型為IMetadataExchange)。由於MEX終結點契約IMetadataExchange的Get方法的輸入參數和輸出參數均為Message對象,而是我們創建Message對象,並指定與WS-MEX匹配的Action。然後傳入通過ChannelFactory<TChannel>創建的服務代理中進行服務調用。最後從回復消息中提取出包含元數據的MetadataSet對象,並將其寫入一個XML文件中。

   1: using System;
2: using System.Diagnostics;
3: using System.ServiceModel;
4: using System.ServiceModel.Channels;
5: using System.ServiceModel.Description;
6: using System.Text;
7: using System.Xml;
8: namespace Artech.MetataRetrieval
9: {
10: class Program
11: {
12: static void Main(string[] args)
13: {
14: MetadataSet metadata = null;
15: using (ChannelFactory<IMetadataExchange> channelFactory = new ChannelFactory<IMetadataExchange>(MetadataExchangeBindings.CreateMexHttpBinding(), new EndpointAddress("http://127.0.0.1:9999/calculatorservice/mex")))
16: {
17: IMetadataExchange proxy = channelFactory.CreateChannel();
18: using (proxy as IDisposable)
19: {
20: Message request = Message.CreateMessage(MessageVersion.Default, "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
21: metadata = proxy.Get(request).GetBody<MetadataSet>();
22: }
23: }
24: using (XmlWriter writer = new XmlTextWriter("metadata.xml", Encoding.UTF8))
25: {
26: metadata.WriteTo(writer);
27: }
28: Process.Start("metadata.xml");
29: }
30: }
31: }

當程序成功執行,包含元數據的XML文件將會通過IE輸出(假設將IE作為默認的XML啟動程序),圖1為運行後的截圖。

圖1 通過IE顯示獲取的元數據(以WS-MEX方式發布)

二、 基於HTTP-GET的元數據獲取

上面我們通過自定的方式成功獲取了服務端以WS-MEX方式發布的元數據,現在我們來是實現基於HTTP-GET的元數據獲取方式。既然服務端采用了基於HTTP-GET的元數據發布方式,那麼就意味著我們可以通過簡單的HTTP請求的方式獲取相應的元數據資源。

同樣是基於上面的例子,仔細的讀者相信已經看到了,在計算服務的配置文件中,除了為服務添加MEX終結點之外,還通過ServiceMetadataBehavior開啟了基於HTTP-GET的元數據發布方式,並將元數據發布地址指定為:http://127.0.0.1:3721/calculatorservice/metadata。

下面的代碼實現了相應的元數據獲取,其中我通過指定目標地址創建了一個HttpWebRequest對象,並通過該對象向元數據的發布地址發送請求。獲取的元數據將以HttpWebResponse的形式返回,由於獲取的元數據實際上是一個WSDL文檔,所以我們可以通過ServiceDescription的Read方法直接讀取生成一個ServiceDescription對象,並最終通過MetadataSection的靜態方法CreateFromServiceDescription將其轉換成一個MetadataSection對象。該MetadataSection對象被最終添加到創建的MetadataSet中,並被寫入一個XML文件。

   1: using System.Diagnostics;
2: using System.Net;
3: using System.ServiceModel.Description;
4: using System.Xml;
5: using System.Text;
6: namespace Artech.MetataRetrieval
7: {
8: class Program
9: {
10: static void Main(string[] args)
11: {
12: MetadataSet metadata = new MetadataSet();
13: HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:3721/calculatorservice/metadata");
14: request.Method = "Get";
15: HttpWebResponse response = (HttpWebResponse)request.GetResponse();
16: using (XmlReader reader = XmlDictionaryReader.CreateTextReader(response.GetResponseStream(), new XmlDictionaryReaderQuotas()))
17: {
18: System.Web.Services.Description.ServiceDescription serviceDesc = System.Web.Services.Description.ServiceDescription.Read(reader);
19: metadata.MetadataSections.Add(MetadataSection.CreateFromServiceDescription(serviceDesc));
20: }
21: using (XmlWriter writer = new XmlTextWriter("metadata.xml", Encoding.UTF8))
22: {
23: metadata.WriteTo(writer);
24: }
25: Process.Start("metadata.xml");
26: }
27: }
28: }

當上面的應用程序成功執行,包含獲取的元數據的XML將會通過IE打開,圖2為運行後的截圖。通過兩種方式獲取的元數據本質上是相同的,不過可能細心的讀者已經發現了:與上面的例子(WS-MEX)獲取的MetadataSet不同,通過HTTP-GET獲取的MetadataSet僅僅包含一個元數據方言(Dialect)為WSDL的MetadataSection。這是因為,前面的例子實際上將WSDL中引用(通過終結點地址或者資源地址)的內容都生成了相應的MetadataSection,在這裡由於篇幅所限,並沒有做這些工作。

圖2 通過IE顯示獲取的元數據(以HTTP-GET方式發布)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved