在ASP.net中,我们可以创建WSDL文件来描述当前提供的HTML或XML或者任何其他非二进制格式)页,可以使用WSDL来生成客户端代理,并使用Visual Studio.NET或WSDL.exe命令行工具创建代理类。最后通过 RegEx 来分析已命名的HTML页和提取值。以下介绍完整的实现过程:
一、为网站编写WSDL文件
我们以访问http://movies.yahoo.com/电影网站中“本周票房排行榜”(Top Box Office)的数据为例,检索出票房排名第一的影片名称。
通过查看http://movies.yahoo.com/网页的HTML源文件,可以看到排名第一影片的链接是:Finding Nemo,为此可在 WSDL 的响应节中添加 标记。这些标记采用一个称为 pattern 的属性,这是与页面上作为属性值的文本部分相对应的正则表达式。这里我们创建的正规表达式是:“pattern="d=hv&cf=info&id=[0-9]*">(.*?) <?xml version="1.0" encoding="gb2312"?> <definitions xmlns:s="http://www.w3.org/2000/10/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s0="http://tempuri.org/" targetNamespace="http://tempuri.org/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:msType="http://microsoft.com/wsdl/mime/textMatching/"> <types/> <message name="GetBookDetailsHttpGetIn"> <part name="isbn" type="s:string"/> </message> <message name="GetBookDetailsHttpGetOut"/> <portType name="BarnesAndNobleHttpGet"> <operation name="GetBookDetails"> <input message="s0:GetBookDetailsHttpGetIn"/> <output message="s0:GetBookDetailsHttpGetOut"/> </operation> </portType> <binding name="BarnesAndNobleHttpGet" type="s0:BarnesAndNobleHttpGet"> <http:binding verb="GET"/> <operation name="GetBookDetails"> <http:operation location=""/> <input> <http:urlEncoded/> </input> <output> <msType:text> <msType:match name="Rank" pattern="d=hv&cf=info&id=[0-9]*">(.*?) </"ignoreCase="true"/> </msType:text> </output> </operation> </binding> <service name="BarnesAndNoble"> <port name="BarnesAndNobleHttpGet" binding="s0:BarnesAndNobleHttpGet"> <http:address location="http://movies.yahoo.com/"/> </port> </service> </definitions>
在上面的WSDL中,定义了BarnesAndNoble类,指定进行检索的站点http://movies.yahoo.com/,由于是一般的通用网站,此服务不使用SOAP,而是使用HTTP GET进行请求。
二、构建WEB服务代理
在Visual Studio.NET中,右键单击“解决方案资源管理器”中的“引用”,选择“添加WEB引用”,就可以打开“添加WEB引用”对话框,
在此对话框中,输入刚才创建好的WSDL文件所在的地址,Visual Studio.NET从指定的位置获取WSDL并验证它。单击“添加引用”按钮,就可以将此WSDL描述的WEB服务的引用添加到当前的工程中。
通过以上操作,Visual Studio.NET在后台自动分析WSDL,并创建了代表Web服务的代理对象,并高速缓存了WSDL的本地副本。如果WSDL内容发生变化,需要手工“更新WEB引用”。
WEB服务代理的源代码如下:
Public Class BarnesAndNoble Inherits System.Web.Services.Protocols.HttpGetClientProtocol '<remarks/> Public Sub New() MyBase.New Me.Url = "http://movies.yahoo.com/" End Sub '<remarks/> <System.Web.Services.Protocols.HttpMethodAttribute(GetType (System.Web.Services.Protocols.TextReturnReader), GetType (System.Web.Services.Protocols.UrlParameterWriter))> _ Public Function GetBookDetails(ByVal isbn As String) As GetBookDetailsMatches Return CType(Me.Invoke("GetBookDetails", (Me.Url + ""), New Object() {isbn}),GetBookDetailsMatches) End Function '<remarks/> Public Function BeginGetBookDetails(ByVal isbn As String, ByVal callback As System.AsyncCallback, ByVal asyncState As Object) As System.IAsyncResult Return Me.BeginInvoke("GetBookDetails", (Me.Url + ""), New Object() {isbn}, callback, asyncState) End Function '<remarks/> Public Function EndGetBookDetails(ByVal asyncResult As System.IAsyncResult) As GetBookDetailsMatches Return CType(Me.EndInvoke(asyncResult),GetBookDetailsMatches) End Function End Class Public Class GetBookDetailsMatches <System.Web.Services.Protocols.MatchAttribute("d=hv&cf=info&id=[0-9]*""> (.*?)</", lgnoreCase:=true)> _ Public Rank As String End Class
如果在“解决方案资源管理器”中展开“Web References”部分,可以看出具体表达方式:
三、在WEB应用程序中编写代码,使用BarnesAndNoble Web服务。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim bn As New localhost.BarnesAndNoble() Dim match As localhost.GetBookDetailsMatches match = bn.GetBookDetails("") rank.Text = match.Rank End Sub 在以上程序中,首先调用New localhost.BarnesAndNoble(),创建代理的一个范例bn。bn再调用GetBookDetails()方法传入参数,最后访回一个Rank值(排名第一的影片名称)。
通过编写WSDL,访问由 WSDL 中的功能化名称调用的 Matches 对象,就可以将任何 HTML 部分作为属性来访问,我们可以轻松地将WEB站点转换为WEB服务。以上程序在Windows2000 Server、Visual Studio.NET中调试通过。 |