Web Service 是一个平台独立的,低耦合的,自包含的、基于可编程的 Web 的应用程序,可使用开放的 XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
声明:本 Chat 所引用的 WebService 服务只用于技术交流,不可用于商业用途。
一、 WebService 是什么?
Web Services 是应用程序组件
Web Services 使用开放协议进行通信
Web Services 是独立的(self-contained)并可自我描述
Web Services 可通过使用 UDDI 来发现
Web Services 可被其他应用程序使用
XML 是 Web Services 的基础
1. SOA 与 Web Service
SOA(Service-Oriented Architecture,面向服务的体系结构)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。
SOA 是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA 可以看作是 B/S 模型、XML/Web Service 技术之后的自然延伸。Web Service 即 Web 服务。
在理解 SOA 和 Web 服务的关系上,经常发生混淆。Web 服务是技术规范,而 SOA 是设计原则。特别是 Web 服务中的 WSDL(Web Services Description Language,Web 服务描述语言),是一个 SOA 配套的接口定义标准,这是 Web 服务和 SOA 的根本联系。从本质上来说,SOA 是一种架构模式,而 Web 服务是利用一组标准实现的服务。Web 服务是实现 SOA 的方式之一。用 Web 服务来实现 SOA 的好处是你可以实现一个中立平台,来获得服务,而且随着越来越多的软件商支持越来越多的 Web 服务规范,你会取得更好的通用性。
Web Service 是解决应用程序之间相互通信的一项技术。严格地说,Web Service 是描述一系列操作的接口。它使用标准的、规范的 XML 描述接口。这一描述中包括与服务进行交互所需要的全部细节,包括消息格式、传输协议和服务位置。而在对外的接口中隐藏了服务实现的细节,仅提供一系列可执行的操作,这些操作独立于软、硬件平台和编写服务所用的编程语言。Web Service 既可单独使用,也可同其他 Web Service 一起,实现复杂的业务功能。
在 Web Service 模型的解决方案中共有三种工作角色,其中服务提供者(服务器)和服务请求者(客户端)是必需的,服务注册中心是一个可选的角色。它们之间的交互和操作构成了 Web Service 的体系结构。服务提供者定义并实现 Web Service,然后将服务描述发布到服务请求者或服务注册中心;服务请求者使用查找操作从本地或服务注册中心检索服务描述,然后使用服务描述与服务提供者进行绑定并调用 Web Service。
2. XML、UDDI、XSD、WSDL
XML(Extensible Markup Language,可扩展标记语言)规定了服务之间以及服务内部数据交换的格式和结构,通过XML 可以将任何文档转换成XML 格式,然后跨越因特网协议传输。XML 是 Web Service 表示数据的基本格式。除了易于建立和易于分析外,XML 主要的优点在于它既是平台无关的,又是厂商无关的。
XML 解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16 位、32 位、还是 64 位?这些细节对实现互操作性都是很重要的。W3C 制定的 XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。Web Service 就是用 XSD 来作为其数据类型系统的。
Web Service 建好以后,你或者其他人就会去调用它。SOAP(Simple Object Access Protocol,简单对象访问协议)提供了标准的 RPC 方法来调用 Web Service。SOAP 规范定义了 SOAP 消息的格式,以及怎样通过 HTTP 协议来使用 SOAP。SOAP 也是基于 XML 和 XSD 的,XML 是 SOAP 的数据编码方式。
Web Service 有什么功能,调用的函数参数数据类型是什么,有几个参数等等,这些描述就需要一种语言,这就是WSDL(Web Services Description Language,Web服务描述语言)了。WSDL 本身其实就是一个标准的 XML 文档,用于描述 Web Service 及其函数、参数和返回值。 UDDI(Universal Description, Discovery and Integration,通用描述、发现与集成服务)是一种目录服务,可以使用它对 Web Services 进行注册和搜索。UDDI 是一个分布式的互联网服务注册机制,它集描述、检索与集成为一体,其核心是注册机制。UDDI 实现了一组可公开访问的接口,通过这些接口,网络服务可以向服务信息库注册其服务信息、服务需求者可以找到分散在世界各地的网络服务。
二、为什么要用 WebService?
通过 Web Service,应用程序可以用标准的方法把功能和数据“暴露”出来,供其它应用程序使用。这样可以将那些使用不同语言写成的、在不同平台上运行的各种程序集成起来。
用 Web Service 来实现 B2B 集成的最大好处在于可以轻易实现互操作性。只要把商务逻辑“暴露”出来,成为 WebService,就可以让任何指定的合作伙伴调用这些商务逻辑,而不管他们的系统在什么平台上运行,使用什么开发语言。
三、如何使用 WebService?
做一些有意思的 Windows 桌面应用程序。本 Chat 重在讲解如何引用并调用 Web Service 服务,因此例子较有趣,简单,适合 Web Service 服务入门学习。
C# 调用 Web Service 服务的大致步骤如下:
添加 Web Service 引用
在 winform 窗体中添加所需控件
调用 Web Service 服务实现相应功能
下面分别举几个具体的例子:
1. 汉英互译词典
在 VS 中创建新的 Windows 窗体程序:
添加服务引用:
在地址栏输入
http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl,点击转到,下面的命名空间可以自定义,最后点击确定
在浏览器中打开网址
http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl,你会发现是这样的
要想看清楚该服务都包含哪些功能,只需要将网址最后的 ?wsdl 删除
该服务中包含以下方法:
GetMp3
获得朗读 MP3 字节流
输入参数:Mp3 = Mp3 名称; 返回数据:字节数组 Byte[]。
SuggestWord
获得候选词
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
Translator
中英文双向翻译 DataSet
输入参数:wordKey = 单词; 返回数据:DataSet。(包括全部数据三个DataTable)
TranslatorReferString
中英文双向翻译(相关词条)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]
TranslatorSentenceString
中英文双向翻译(例句)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
TranslatorString
中英文双向翻译(基本)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
在 winform 窗体中添加控件,如下所示
在 Button 的单击事件中添加代码
private void TranslateButton_Click(object sender, EventArgs e)
{
ServiceReference1.EnglishChineseSoapClient Translate = new ServiceReference1.EnglishChineseSoapClient();
string input = this.inputText.Text;
if (string.IsNullOrEmpty(input)) return;
this.outputText.Lines = Translate.TranslatorString(input);
}
2. 查询 QQ 号码是否在线
添加 Web Service 服务地址
http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl
其中包含方法:
qqCheckOnline
获得腾讯 QQ 在线状态
输入参数:QQ 号码 String,默认 QQ 号码:8698053。返回数据:String,Y = 在线;N = 离线;E = QQ 号码错误;A = 商业用户验证失败;V = 免费用户超过数量
添加合适的控件
本例中调用的方法如下:
private void CheckOnlineButton_Click(object sender, EventArgs e)
{ ServiceReferenceQQ.qqOnlineWebServiceSoapClient OnLine = new ServiceReferenceQQ.qqOnlineWebServiceSoapClient();
string QQCode = this.QQText.Text;
if (string.IsNullOrEmpty(QQCode)) return;
string result = OnLine.qqCheckOnline(QQCode);
switch (result)
{
case "Y":
this.label1.Text = "在线";
break;
case "N":
this.label1.Text = "不在线";
break;
default:
this.label1.Text = "QQ号码错误";
break;
}
}
3. 汉语简体和繁体相互转换
添加 Web Service 服务地址
http://ws.webxml.com.cn/WebServices/TraditionalSimplifiedWebService.asmx?wsdl
该服务包含以下方法:
toSimplifiedChinese
繁体字转换为简体字
输入参数:sText = 字符串; 返回数据:字符串。
toTraditionalChinese
简体字转换为繁体字
输入参数:sText = 字符串; 返回数据:字符串。
添加合适的控件如下:
调用 Web Service 服务的代码如下:
private void ToSimplifiedChinese_Click(object sender, EventArgs e)
{ ServiceReferenceTraditionalSimplified.TraditionalSimplifiedWebServiceSoapClient TraditionalSimplified = new ServiceReferenceTraditionalSimplified.TraditionalSimplifiedWebServiceSoapClient();
string input = this.richTextBox1.Text;
if (string.IsNullOrEmpty(input)) return;
string result = TraditionalSimplified.toSimplifiedChinese(input);
this.richTextBox2.Text = result;
}
private void ToTraditionalChineseButton_Click(object sender, EventArgs e
{ServiceReferenceTraditionalSimplified.TraditionalSimplifiedWebServiceSoapClient TraditionalSimplified = new ServiceReferenceTraditionalSimplified.TraditionalSimplifiedWebServiceSoapClient();
string input = this.richTextBox1.Text;
if (string.IsNullOrEmpty(input)) return;
string result = TraditionalSimplified.toTraditionalChinese(input);
this.richTextBox2.Text = result;
}
4. 火车车次时刻表查询
添加 Web Service 服务地址
http://ws.webxml.com.cn/WebServices/TrainTimeWebService.asmx?wsdl
该服务中包含以下方法:
getDetailInfoByTrainCode
通过火车车次查询列车经由车站明细 DataSet
输入参数:车次代号字符串,空字符串默认上海到北京 D32 次,UserID = 商业用户 ID(普通用户不需要);返回数据:DataSet,Item.(TrainStation)=车站名称、Item.(ArriveTime)=到站时间、Item.(StartTime)=发车时间、Item.(KM)=里程(KM)
getStationAndTimeByStationName
通过发车站和到达站查询火车时刻表 DataSet
输入参数:StartStation = 发车站,ArriveStation = 到达站(支持第一个字匹配模糊查询),空字符串默认发车站上海和到达站北京,UserID = 商业用户 ID(普通用户不需要);返回数据:DataSet,Item.(TrainCode)=车次、Item.(FirstStation)=始发站、Item.(LastStation)=终点站、Item.(StartStation)=发车站、Item.(StartTime)=发车时间、Item.(ArriveStation)=到达站、Item.(ArriveTime)=到达时间、Item.(KM)=里程(KM)、Item.(UseDate)=历时
getStationAndTimeByTrainCode
通过火车车次查询火车时刻表 String()
输入参数:车次代号字符串,空字符串默认上海到北京 D32 次,UserID =
商业用户 ID(普通用户不需要);返回数据:一个一维字符串数组 String(9),String(0)=车次、String(1)=始发站、String(2)=终点站、String(3)=发车站、String(4)=发车时间、String(5)=到达站、String(6)=到达时间、String(7)=里程(KM)、String(8)=历时、String(9)=空字符串(备用)
getStationAndTimeDataSetByLikeTrainCode
通过火车车次查询本火车时刻表(支持模糊查询) DataSet
输入参数:车次代号字符串(支持模糊查询),空字符串默认上海到北京 D32 次,UserID = 商业用户 ID(普通用户不需要);返回数据:DataSet,Item.(TrainCode)=车次、Item.(FirstStation)=始发站、Item.(LastStation)=终点站、Item.(StartStation)=发车站、Item.(StartTime)=发车时间、Item.(ArriveStation)=到达站、Item.(ArriveTime)=到达时间、Item.(KM)=里程(KM)、Item.(UseDate)=历时
getStationAndTimeDataSetByTrainCode
通过火车车次查询本火车时刻表 DataSet
输入参数:车次代号字符串,空字符串默认上海到北京 D32 次,UserID = 商业用户 ID(普通用户不需要);返回数据:DataSet,Item.(TrainCode)=车次、Item.(FirstStation)=始发站、Item.(LastStation)=终点站、Item.(StartStation)=发车站、Item.(StartTime)=发车时间、Item.(ArriveStation)=到达站、Item.(ArriveTime)=到达时间、Item.(KM)=里程(KM)、Item.(UseDate)=历时
getStationName
获得本火车时刻表 Web Services 的全部始发站名称
输入参数:无,输出参数 String()
getStationNameDataSet
获得本火车时刻表 Web Services 支持的全部站台名称和拼音缩写 DataSet
输入参数:无;返回数据:结构为站台名称、拼音缩写,按拼音缩写升序排列
getVersionTime
获得本火车时刻表 Web Services 的数据库版本更新时间
输入参数:无,输出参数 String
添加合适的控件
查询按钮事件代码如下:
private void button1_Click(object sender, EventArgs e){
ServiceReferenceTrainTime.TrainTimeWebServiceSoapClient TrainTime = new ServiceReferenceTrainTime.TrainTimeWebServiceSoapClient();
string[] traintimeinfo = TrainTime.getStationAndTimeByTrainCode("1461","");
if (traintimeinfo.Length == 0) return;
this.trainrichTextBox.Lines = traintimeinfo;
}
5. Email 电子邮件地址验证
添加 Web Service 服务地址
http://ws.webxml.com.cn/WebServices/ValidateEmailWebService.asmx?wsdl
该服务包含以下方法:
ValidateEmailAddress
验证 Email 地址是否正确
输入参数:EmailAddress = Email 地址(默认SMTP端口25),返回数据: Byte 字节。返回值: 0 = 请重新验证;1 = 邮件地址合法;2 = 只是域名正确;3 = 一个未知错误;4 = 邮件服务器没有找到;5 = 电子邮件地址错误;6 = 免费用户验证超过数量(50次/24小时);7 = 商业用户不能通过验证
ValidateEmailAddressPro
验证 Email 地址是否正确
输入参数:EmailAddress = Email 地址,theEmailPort = SMTP端口(Integer),返回数据: Byte 字节。返回值同 ValidateEmailAddress
添加相应的框架
查询代码如:
private void button3_Click(object sender, EventArgs e)
{
ServiceReferenceEmail.ValidateEmailWebServiceSoapClient Email = new ServiceReferenceEmail.ValidateEmailWebServiceSoapClient();
string emailAddress = this.EmailtextBox.Text;
if (string.IsNullOrEmpty(emailAddress)) return;
byte b = Email.ValidateEmailAddress(emailAddress);
string result;
switch (b)
{
case 0:
result = "请重新验证";
break;
case 1:
result = "邮件地址合法";
break;
default:
result = "错误";
break;
}
this.textBox2.Text = result;
}
6. 国内手机号码归属地查询
添加 Web Service 服务地址
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
该服务包含以下方法:
getDatabaseInfo
获得国内手机号码归属地数据库信息
输入参数:无;返回数据:一维字符串数组(省份 城市 记录数量)。
getMobileCodeInfo
获得国内手机号码归属地省份、地区和手机卡类型信息
输入参数:mobileCode = 字符串(手机号码,最少前7位数字),userID = 字符串(商业用户ID) 免费用户为空字符串;返回数据:字符串(手机号码:省份 城市 手机卡类型)。
添加控件
查询按钮的点击事件的代码
private void button2_Click(object sender, EventArgs e)
{
ServiceReferenceMobileCode.MobileCodeWSSoapClient MobileCode = new ServiceReferenceMobileCode.MobileCodeWSSoapClient();
string mobileCode = this.textBox1.Text;
if (string.IsNullOrEmpty(mobileCode)) return;
string result = MobileCode.getMobileCodeInfo(mobileCode, "");
this.richTextBox3.Text = result;
}
完整窗体及效果如下:
这样,通过中英词典、QQ 号码在线查询、汉字繁体简体转换、列车时刻、Email 地址验证和手机号码归属地查询等 6 个例子展示了 C# 调用 WebService 服务的过程。
附上源代码永久下载链接
欢迎交流学习。
本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。