标签:
基础的 Web Services 平台是 XML + HTTP。
HTTP 协议是最常用的因特网协议。
XML 提供了一种可用于不同的平台和编程语言之间的语言。
此文主要讲。通过Web Services 的WSDL生成C#代码
WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问。
首先来创建一个简单的服务,创建一个空Web应用程序,右键添加新建项,选择web服务,根据自己的需求命名
创建成功了。打开服务,生成了默认的文件代码
首先啥都不管,先运行看看,
DataInfo.asmx文件跟aspx文件一样,可以直接选中。右键在浏览器中查看
自此。你就看到了一个最简单的服务界面
这样你把这个服务发布到服务器。客户端就可以调用了。
现在手动调用试试,单击 "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 。那么把这个接口拖到项目中。继承接口试试。
标签:
原文地址:http://www.cnblogs.com/nsky/p/4491365.html