基礎的 Web Services 平臺是 XML + HTTP。web
HTTP 協議是最經常使用的因特網協議。編程
XML 提供了一種可用於不一樣的平臺和編程語言之間的語言。瀏覽器
此文主要講。經過Web Services 的WSDL生成C#代碼服務器
WSDL(網絡服務描述語言,Web Services Description Language)是一門基於 XML 的語言,用於描述 Web Services 以及如何對它們進行訪問。網絡
首先來建立一個簡單的服務,建立一個空Web應用程序,右鍵添加新建項,選擇web服務,根據本身的需求命名app
建立成功了。打開服務,生成了默認的文件代碼async
首先啥都無論,先運行看看,編程語言
DataInfo.asmx文件跟aspx文件同樣,能夠直接選中。右鍵在瀏覽器中查看ide
自此。你就看到了一個最簡單的服務界面工具
這樣你把這個服務發佈到服務器。客戶端就能夠調用了。
如今手動調用試試,單擊 "HelloWorld"
如今來嘗試代碼調用。把DataInfo.asmx服務發佈到IIS。就比如別人發佈了Web Services,如今我來調用
既然是測試。我就不用打開電腦的IIS了。用一卡西尼服務器便可。就是這個:CassiniDev4
這裏提供一個下載地址:http://cassinidev.codeplex.com/
全路徑就是這個:http://localhost:32768/DataInfo.asmx。在url地址欄打開就能看到
那麼地址有了。在項目中就能夠引用這個服務。
爲了測試。這裏在服務新增一個方法,返回兩個數的和:Add(int x, int y)
1 /// <summary> 2 /// 返回兩個數的和 3 /// </summary> 4 /// <param name="x"></param> 5 /// <param name="y"></param> 6 /// <returns></returns> 7 [WebMethod(Description = "返回兩數的和")] 8 public int Add(int x, int y) 9 { 10 return x + y; 11 }
方法名稱上面添加WebMethod特性後。才能暴露在客戶端,也就是說能夠從遠程Web客戶端調用該方法
Description是對該方法的描述信息,會顯示在客戶端。添加完成,保存,F6從新生成代碼。刷新瀏覽器你能夠看到代碼已經更新
好了。目前爲止。服務已經配置好。而且已經發布。供別人無償使用。當有須要計算兩個數之和的。就能夠調用該服務
如今編寫一個測試代碼。建立一個項目。右鍵引用。選擇添加服務引用
輸入服務地址,命名。單擊肯定便可。固然你也能夠看看該服務提供了那些方法。單擊 "發現"
單擊肯定後。你發現。項目中已經生成了對該服務的引用
如今來編碼調用裏面的Add方法。建立一個頁面。輸入如下代碼
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 GetInfo.DataInfoSoapClient client = new GetInfo.DataInfoSoapClient(); 4 int result = client.Add(9, 10); 5 Response.Write(result); 6 }
運行項目。成功的獲得值爲:19
那你有沒有想過。當添加服務的引用後。內部都作了些什麼。爲何添加之後就能夠調用了呢?
把光標定位到Add方法。按F12轉到方法的定義。
能夠看到。其實已經生成了服務端的代碼。
那這個代碼在哪裏呢。你根據項目的層次結構。
到項目的路徑中看一看
打開Reference.cs 類。你會發現。裏面生成了服務器代碼。是自動生成的。別問我怎麼知道的。它告訴個人:)
其實引用服務後,就生成服務的客戶端代理類
哪天那個發佈服務的人。一不當心。把Add方法的 "+" 改爲了 "*",
1 [WebMethod(Description = "返回兩數的和")] 2 public int Add(int x, int y) 3 { 4 return x * y; 5 }
客戶端也會相應的更新,這就是一個同步更新
你也會發現。web.config裏面有對服務的引用,
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="DataInfoSoap" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:9213/DataInfo.asmx" binding="basicHttpBinding" bindingConfiguration="DataInfoSoap" contract="GetInfo.DataInfoSoap" name="DataInfoSoap" /> </client> </system.serviceModel> </configuration>
來分析下<system.serviceModel>.... </system.serviceModel>節點的含義
<!--此配置節包含全部 Windows Communication Foundation (WCF) ServiceModel 配置元素。--> <system.serviceModel> <!-- 此節包含標準綁定和自定義綁定的集合。 每一項均由其惟一的 name 進行標識。 服務經過用 name 與綁定進行連接來使用綁定。 --> <bindings> <!--綁定配置--> <basicHttpBinding> <!--每一項均由其惟一的 name 進行標識--> <binding name="DataInfoSoap" /> </basicHttpBinding> </bindings> <!--此節包含客戶端用來鏈接到服務的終結點的列表。--> <client> <!--終結點配置--> <endpoint address="http://localhost:9213/DataInfo.asmx" binding="basicHttpBinding" bindingConfiguration="DataInfoSoap" contract="GetInfo.DataInfoSoap" name="DataInfoSoap" /> </client> </system.serviceModel>
詳情:https://msdn.microsoft.com/zh-cn/library/ms731354
既然有人提供服務。也就會有人使用服務,
網上有不少對外公開的服務,好比:
獲取天氣的服務:http://www.webxml.com.cn/WebServices/WeatherWS.asmx
騰訊QQ查詢狀態:http://webservice.webxml.com.cn/webservices/qqOnlineWebService.asmx
這些都是人家提供好了的。你只要直接在項目中引用。就像我上面的那樣,在項目中引用其服務便可。由於這些是公共的。私有的另當別論。
但你有沒有想過,若是你跟別人協同開發項目的時候。一個提供web服務,一個使用web服務。一個已經實現功能的WebService會發布本身的WSDL文件並不會發佈到本身的服務器。那怎麼辦呢?
首先看看什麼是WSDL?
WSDL(網絡服務描述語言,Web Services Description Language)是一門基於 XML 的語言,用於描述 Web Services 以及如何對它們進行訪問。
在服務後面加上wsdl
http://localhost:32768/DataInfo.asmx?wsdl。就能夠獲得當前服務的wsdl文件
而後把這個頁面保存。保存爲.wsdl文件便可,好比我保存在路徑:
其實這樣你依然能夠在項目中添加該服務,地址爲該路徑便可
這樣一樣能夠生成服務端C#代碼,還有一種簡單的方法。
使用VS2010提供的工具wsdl.exe由WSDL文件生成cs文件
看到界面:
輸入wsdl回車,查看介紹
來分析下幾個經常使用的命令:
默認爲C#語言:
生成代碼命令:
生成接口命令:
wsdl用法:
好了。如今來生成一個C#代碼看看
1:根據url路徑生成代碼,我的感受沒什麼實際意義
來看看這條命令
wsdl是命令開始
/o:是開始輸出
/o:後面是服務地址
生成的代碼默認路徑在
2:根據本地wsdl文件生成代碼。若是上面的生成目錄想根據本身來定義話。能夠這樣在 命令/o: 帶上位置
從圖片的標記能夠看出來。已經成功了
來看看生成後的代碼:
1 //------------------------------------------------------------------------------ 2 // <auto-generated> 3 // 此代碼由工具生成。 4 // 運行時版本:4.0.30319.18444 5 // 6 // 對此文件的更改可能會致使不正確的行爲,而且若是 7 // 從新生成代碼,這些更改將會丟失。 8 // </auto-generated> 9 //------------------------------------------------------------------------------ 10 11 using System; 12 using System.ComponentModel; 13 using System.Diagnostics; 14 using System.Web.Services; 15 using System.Web.Services.Protocols; 16 using System.Xml.Serialization; 17 18 // 19 // 此源代碼由 wsdl 自動生成, Version=4.0.30319.1。 20 // 21 22 23 /// <remarks/> 24 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 25 [System.Diagnostics.DebuggerStepThroughAttribute()] 26 [System.ComponentModel.DesignerCategoryAttribute("code")] 27 [System.Web.Services.WebServiceBindingAttribute(Name="DataInfoSoap", Namespace="http://tempuri.org/")] 28 public partial class DataInfo : System.Web.Services.Protocols.SoapHttpClientProtocol { 29 30 private System.Threading.SendOrPostCallback HelloWorldOperationCompleted; 31 32 private System.Threading.SendOrPostCallback AddOperationCompleted; 33 34 /// <remarks/> 35 public DataInfo() { 36 this.Url = "http://localhost:32768/DataInfo.asmx"; 37 } 38 39 /// <remarks/> 40 public event HelloWorldCompletedEventHandler HelloWorldCompleted; 41 42 /// <remarks/> 43 public event AddCompletedEventHandler AddCompleted; 44 45 /// <remarks/> 46 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 47 public string HelloWorld() { 48 object[] results = this.Invoke("HelloWorld", new object[0]); 49 return ((string)(results[0])); 50 } 51 52 /// <remarks/> 53 public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) { 54 return this.BeginInvoke("HelloWorld", new object[0], callback, asyncState); 55 } 56 57 /// <remarks/> 58 public string EndHelloWorld(System.IAsyncResult asyncResult) { 59 object[] results = this.EndInvoke(asyncResult); 60 return ((string)(results[0])); 61 } 62 63 /// <remarks/> 64 public void HelloWorldAsync() { 65 this.HelloWorldAsync(null); 66 } 67 68 /// <remarks/> 69 public void HelloWorldAsync(object userState) { 70 if ((this.HelloWorldOperationCompleted == null)) { 71 this.HelloWorldOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloWorldOperationCompleted); 72 } 73 this.InvokeAsync("HelloWorld", new object[0], this.HelloWorldOperationCompleted, userState); 74 } 75 76 private void OnHelloWorldOperationCompleted(object arg) { 77 if ((this.HelloWorldCompleted != null)) { 78 System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); 79 this.HelloWorldCompleted(this, new HelloWorldCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); 80 } 81 } 82 83 /// <remarks/> 84 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Add", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 85 public int Add(int x, int y) { 86 object[] results = this.Invoke("Add", new object[] { 87 x, 88 y}); 89 return ((int)(results[0])); 90 } 91 92 /// <remarks/> 93 public System.IAsyncResult BeginAdd(int x, int y, System.AsyncCallback callback, object asyncState) { 94 return this.BeginInvoke("Add", new object[] { 95 x, 96 y}, callback, asyncState); 97 } 98 99 /// <remarks/> 100 public int EndAdd(System.IAsyncResult asyncResult) { 101 object[] results = this.EndInvoke(asyncResult); 102 return ((int)(results[0])); 103 } 104 105 /// <remarks/> 106 public void AddAsync(int x, int y) { 107 this.AddAsync(x, y, null); 108 } 109 110 /// <remarks/> 111 public void AddAsync(int x, int y, object userState) { 112 if ((this.AddOperationCompleted == null)) { 113 this.AddOperationCompleted = new System.Threading.SendOrPostCallback(this.OnAddOperationCompleted); 114 } 115 this.InvokeAsync("Add", new object[] { 116 x, 117 y}, this.AddOperationCompleted, userState); 118 } 119 120 private void OnAddOperationCompleted(object arg) { 121 if ((this.AddCompleted != null)) { 122 System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); 123 this.AddCompleted(this, new AddCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); 124 } 125 } 126 127 /// <remarks/> 128 public new void CancelAsync(object userState) { 129 base.CancelAsync(userState); 130 } 131 } 132 133 /// <remarks/> 134 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 135 public delegate void HelloWorldCompletedEventHandler(object sender, HelloWorldCompletedEventArgs e); 136 137 /// <remarks/> 138 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 139 [System.Diagnostics.DebuggerStepThroughAttribute()] 140 [System.ComponentModel.DesignerCategoryAttribute("code")] 141 public partial class HelloWorldCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { 142 143 private object[] results; 144 145 internal HelloWorldCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 146 base(exception, cancelled, userState) { 147 this.results = results; 148 } 149 150 /// <remarks/> 151 public string Result { 152 get { 153 this.RaiseExceptionIfNecessary(); 154 return ((string)(this.results[0])); 155 } 156 } 157 } 158 159 /// <remarks/> 160 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 161 public delegate void AddCompletedEventHandler(object sender, AddCompletedEventArgs e); 162 163 /// <remarks/> 164 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 165 [System.Diagnostics.DebuggerStepThroughAttribute()] 166 [System.ComponentModel.DesignerCategoryAttribute("code")] 167 public partial class AddCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { 168 169 private object[] results; 170 171 internal AddCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 172 base(exception, cancelled, userState) { 173 this.results = results; 174 } 175 176 /// <remarks/> 177 public int Result { 178 get { 179 this.RaiseExceptionIfNecessary(); 180 return ((int)(this.results[0])); 181 } 182 } 183 }
一眼是否是就看到了熟悉的代碼?,對。
這個url就是服務的地址,更多的信息你能夠本身去看裏面的代碼,分析分析。
把這個類拖到你的項目中,測試
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 /* 4 GetInfo.DataInfoSoapClient client = new GetInfo.DataInfoSoapClient(); 5 int result = client.Add(9, 10); 6 Response.Write(result); 7 * */ 8 9 DataInfo info = new DataInfo(); 10 int result = info.Add(9, 5); 11 Response.Write(result); 12 }
若是想生成其餘語言呢。好比vb ,從這裏能夠看出命令:
那就動手嘗試下
還能夠生成接口:經過/si命令
你會發現。保存的路徑並非D:\data,由於/si 命令沒有這個選項,那怎麼辦呢?能夠切換到D:\data目錄
很顯然。此次是我想要的結果了
看生成的代碼是否是很簡潔呢?
1 //------------------------------------------------------------------------------ 2 // <auto-generated> 3 // 此代碼由工具生成。 4 // 運行時版本:4.0.30319.18444 5 // 6 // 對此文件的更改可能會致使不正確的行爲,而且若是 7 // 從新生成代碼,這些更改將會丟失。 8 // </auto-generated> 9 //------------------------------------------------------------------------------ 10 11 using System; 12 using System.ComponentModel; 13 using System.Diagnostics; 14 using System.Web.Services; 15 using System.Web.Services.Protocols; 16 using System.Xml.Serialization; 17 18 // 19 // 此源代碼由 wsdl 自動生成, Version=4.0.30319.1。 20 // 21 22 23 /// <remarks/> 24 [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 25 [System.Web.Services.WebServiceBindingAttribute(Name="DataInfoSoap", Namespace="http://tempuri.org/")] 26 public interface IDataInfoSoap { 27 28 /// <remarks/> 29 [System.Web.Services.WebMethodAttribute()] 30 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 31 string HelloWorld(); 32 33 /// <remarks/> 34 [System.Web.Services.WebMethodAttribute()] 35 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Add", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 36 int Add(int x, int y); 37 }
能夠看到接口的名稱是 IDataInfoSoap 。那麼把這個接口拖到項目中。繼承接口試試。