老老實實學WCFcss
第六篇 元數據交換html
經過前兩篇的學習,咱們瞭解了WCF通訊的一些基本原理,咱們知道,WCF服務端和客戶端經過共享元數據(包括服務協定、服務器終結點信息)在兩個終結點上創建通道從而進行通訊。咱們經過手寫代碼(或配置)的方式爲服務端編寫了元數據信息,沒有藉助元數據交換就實現了通訊。然而在實際應用中,元數據每每是不少的,並且重複編寫元數據的工做也是不值得的,所以必然會用到元數據交換的方式讓客戶端獲取元數據,本篇咱們就來進一步瞭解一下元數據和元數據交換。java
1. 元數據是怎樣提供的web
咱們知道,元數據包括了要和服務端進行通訊的全部信息,包括服務協定接口、服務端終結點地址、綁定等信息,它指出了客戶端應該到何處去尋找服務以及怎樣調用服務的一切線索。可是服務端是怎樣公佈其元數據的呢?編程
答案是使用WSDL文件,WSDL即Web Service Description Language,Web服務描述語言,它是一個XML文件,在這個文件中按照必定的標準來對Web Service進行描述,他是符合W3C標準的,由於WCF是被設計爲供不一樣平臺調用的服務框架,因此客戶端多是非微軟平臺的,好比Java什麼的。所以WCF必須使用WSDL這種國際標準的描述方法來描述服務才能被衆多的平臺所訪問。瀏覽器
2. 元數據交換的過程是怎樣的ruby
在WCF服務端的運行時,有一組類庫隨時待命把服務的元數據輸出爲WSDL描述提供給請求者,只要有客戶端按照服務端約定的方法來請求元數據,服務端當即將服務運行時狀態寫成WSDL文件提供。客戶端獲得的實際上就是WSDL文件(還有一些框架描述文件XSD),客戶端拿到文件後再使用本身的方法來解讀WSDL,把他翻譯成客戶端可用的源代碼或配置文件,這時客戶端就獲得了服務的編程模型,經過一些代理類,客戶端甚至能夠像調用本地對象同樣使用WCF服務。服務器
所以整個過程是這樣:客戶端向服務端請求元數據交換-->服務端運行時將元數據編寫成WSDL文件提供-->客戶端得到文件-->客戶端翻譯文件-->客戶端根據翻譯結果生成本地類代碼和配置-->客戶端得到服務的本地編程模型。架構
這就是元數據交換的過程。app
3. 得到WSDL
在微軟平臺中,有兩種方法來進行元數據交換,第一是使用服務引用,第二是使用元數據實用工具(svcutil.exe)來進行,咱們先學習這個工具。
這個工具能夠在Windows SDK中找到,具體位置爲 C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin,若是你有VS2010,能夠啓動VS2010的命令行工具,這樣就能夠在任何目錄下使用這個程序。
咱們先看一個例子,就是咱們在前幾篇中創建的IIS服務HelloWCFService,它被我寄宿在IIS中。
源代碼以下(HelloWCF.cs):
using System; using System.ServiceModel; namespace LearnWCF { [ ServiceContract] public interface IHelloWCF { [ OperationContract] string HelloWCF(); } public class HelloWCFService : IHelloWCF { public string HelloWCF() { return "Hello WCF!"; } } }
配置文件(web.config)以下:
<configuration> <system.serviceModel> <services> <service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange"> <endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="metadataExchange"> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
在瀏覽器中輸入服務地址會以下圖所示:
看到系統提示的那行命令了麼?系統在告訴咱們如何使用svcutil.exe來得到元數據。咱們如今試一下,首先打開VS2010命令行:
開始-->全部程序-->Visual Studio 2010-->Visual Studio Tools-->Visual Studio命令行提示
命令行工具的窗口是這樣的:
咱們導航到一個目錄下準備得到元數據文件。
咱們暫時不按照瀏覽器提供給咱們的方法作,由於按照那個方法作就把得到WSDL和翻譯WSDL爲客戶端代碼合在一塊兒了,咱們先得到WSDL元數據文件,看看它是什麼樣子的。咱們按以下的指令作:
svcutil.exe /t:metadata http://localhost/iisservice/hellowcfservice.svc?wsdl
咱們加入了一個參數/t:metadata 表示只輸出元數據,不生成代碼。命令的執行過程以下:
能夠看到生成了3個文件,包括兩個架構文件和一個WSDL文件,這些就是服務端元數據的描述了,全部的客戶端請求到的實際上都是這個文件。WSDL的規範比較多,關於它的內容,咱們從此再展開來看,不過簡單的打開看一下就能看出一些與服務協定、綁定、操做這些東西相關的地方。
4. 翻譯WSDL文件
WSDL是一個XML文件,其實就是個文本文件,客戶端必須將其按照本身的平臺特色把他翻譯成本地代碼文件來使用。svcutil固然會提供這個功能。在wsdl文件所在目錄下使用以下的命令就能夠把WSDL文件翻譯成本地代碼文件:
svcutil *.wsdl *.xsd
顧名思義,就是根據當前目錄下的全部的WSDL文件和XSD文件來生成客戶端代碼文件。過程會是這樣:
能夠看到,生成了一個cs文件和一個配置文件,這些就是根據WSDL文件翻譯成的客戶端代碼文件了。打開來看看,必定不陌生,就是使用ClientBase<>來生成一個客戶端代理類並把終結點的信息配置在了.config文件裏。把這兩個文件包含在客戶端的項目中並把output.config改爲app.config就能夠了。
4. 更好地使用元數據交換工具
以前咱們瞭解了使用svcuitl.exe來獲取WSDL並翻譯成客戶端代碼的過程。實際上這兩步能夠合二爲一。直接執行下面的命令能夠直接得到客戶端文件:
svcutil.exe http://localhost/iisservice/hellowcfservice.svc?wsdl
這樣它就不會生成WSDL而直接生成客戶端文件了。
不過按照這樣的方式生成的文件可能不太符合咱們的要求,咱們能夠加上一些參數來指定咱們輸出的文件名:
svctuil.exe /out:ClientProxy.cs /config:app.config http://localhost/iisservice/hellowcfservice.svc?wsdl
這樣輸出的文件咱們就能夠直接包含在客戶端項目中使用了。
5. 使用服務引用
其實使用服務引用跟使用svcutil.exe生成的客戶端模型是同樣的,不過服務引用保留了WSDL文件(以及一些相關的七七八八的文件),沒有svcutil.exe來得那麼清爽,可是它跟VS2010集成,使用起來很簡單,並且當服務發生變化時,只須要右擊服務引用選擇更新服務就能夠從新下載WSDL了。
6. 展開一點點
做爲服務端,公開元數據是須要配置的,不一樣的配置會致使元數據公開的方式不一樣。
咱們要記住,WCF服務端公開元數據必須具有兩個條件:
(1) 爲服務添加ServiceMetadata行爲。
(2) 打開元數據交換終結點。
兩者缺一不可。
WCF的公開元數據的手段主要有兩種:
第一種:經過HTTP GET方法。
這就是在前文中咱們看到的方法,咱們可使用HTTP Get的方法來得到WSDL文件即在服務地址.svc後面跟上?wsdl的方法直接請求到WSDL文件。咱們能夠直接在瀏覽器中輸入服務端地址.svc?wsdl,瀏覽器就直接得到了WSDL文件併爲咱們顯示出來了。
還有相應的框架描述文件(XSD)
若是想採用這種元數據公開方式,必須配置服務的ServiceMetadata行爲,並指定httpGetEnabled = "true",而元數據公開終結點沒必要配置,系統會自動配置一個,配置文件的寫法以下:
<configuration> <system.serviceModel> <services> <service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange"> <endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="metadataExchange"> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>在這種配置下,訪問元數據的方法是訪問下面的地址:
http://localhost/iisservice/hellowcfService.svc?wsdl
第二種:經過MEX元數據交換終結點。在這種方式下,咱們首先要保證服務擁有ServiceMetadata行爲,可是httpGetEnabled能夠沒必要爲true。此外咱們還須要爲服務顯式地添加一個終結點,這個終結點的地址、綁定和協定都是指定的咱們不能更改
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
配置文件的寫法以下:
<configuration> <system.serviceModel> <services> <service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange"> <endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="metadataExchange"> <serviceMetadata /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
若是按這種配置,咱們必須按照以下地址來訪問公開的元數據
http://localhost/iisservice/hellowcfservice.svc/mex
注意,因爲沒有開啓HTTP GET,咱們不能在瀏覽器中直接輸入這個地址來獲取WSDL了(會提示400錯誤),咱們必須經過svcutil.exe或添加服務引用的方式來訪問。
使用svcutil.exe或服務引用的時候能夠不關心元數據公開方式是HTTP GET仍是Mex,他們會自動尋找到合適的方式,只須要把服務的svc文件地址輸入就能夠了,可是咱們應該知道,這兩種元數據公開的方式是有區別的。
6. 總結
經過今天的學習,咱們進一步瞭解了WCF元數據的和元數據交換的原理。雖然咱們在實際工程中都會而且應該使用元數據交換工具來幫助提升效率,可是這背後發生的全部環節也是咱們應該掌握的。
相關資源
MSDN關於Svcutil.exe用法的文檔