Web服务和ASPNET.docx
《Web服务和ASPNET.docx》由会员分享,可在线阅读,更多相关《Web服务和ASPNET.docx(39页珍藏版)》请在冰豆网上搜索。
![Web服务和ASPNET.docx](https://file1.bdocx.com/fileroot1/2023-1/10/5cc1a2de-4664-4c8e-ac1a-cb00d05912ec/5cc1a2de-4664-4c8e-ac1a-cb00d05912ec1.gif)
Web服务和ASPNET
Web服务和ASP.NET
本章的内容如下:
●SOAP和WSDL的语法
●如何通过Web服务使用SOAP和WSDL
●提供和使用Web服务
●Web服务的用法。
●使用SOAP标题交换数据
Web服务是利用SOAP(SimpleObjectAccessProtocol,简单对象访问协议)在HTTP上执行远程
方法调用的一种新方法。
过去这个问题一直非常棘手,因为使用过任何DCOM(分布式COM)的人
们,在实例化远程服务器上的对象、调用方法和获取结果时感到非常麻烦,并且在进行必要的配置
时,需要具有很高的技巧。
SOAP的出现使事情变得简单多了。
SOAP技术是一个基于XML的标准,它详细描述了怎样在
HTTP上以可重复的方式进行方法调用。
远程SOAP服务器能够理解这些调用并执行所有困难的工
作,如实例化所需的对象、进行调用以及给客户端返回SOAP格式的响应等。
通过.NETFramework,可以非常容易地利用上述技术。
与ASP.NET一样,我们可以在服务器上使
用完整的C#和.NET技术,而且(也许是更重要的)可以从任何平台上通过HTTP访问服务器,从而实现
的Web服务的简单利用。
换句话说,例如,Linux代码就可以使用.NETWeb服务,或者Internet启用的
电冰箱。
过去作者就曾经成功地把ASP.NETWeb服务和MacromediaFlash组合在一起,创建启用数据
的Flash内容。
此外,也可以使用WSDL(WebServiceDescriptionLanguage,Web服务描述语言)完整地描述Web
服务,还可以在运行期间动态地查找Web服务。
WSDL使用带有XML架构的XML提供对所有方
法的描述(以及对调用方法所需类型的描述)。
现在各式各样的类型可用于Web服务,既有简单的基
元类型,又有完整的DataSet对象,这样,完全存储在内存中的数据库就可以被编组到客户端,从
而大大减少加数据库服务器上加载的数据量。
55第章
注意,本章讨论的是ASP.NETWeb服务,而不是WCFWeb服务,后者是近期才
添加到.NET中。
ASP.NETWeb服务使用起来比较简单,足以满足大多数需要,而
WindowsCommunicationFoundation(WCF)Web服务包含ASP.NETWeb服务的全部功
能,还添加了额外的功能。
WCF详解第43章。
C#高级编程(第7版)
E240
55.1SOAP
如前所述,SOAP是一个与Web服务交换数据的方法。
有关这项技术的书有很多,尤其是微软
公司决定在.NETFramework中采用这项技术之后,SOAP方面的书就更多了。
稍微考虑一下,可以
发现SOAP的工作原理和HTTP的工作原理比较相似,这非常有趣,但并不是必需的。
大多数情况下,
我们不必考虑与Web服务进行交换时所采用的格式,只要得到希望的结果就够了。
因此,本节不深入探讨SOAP的技术细节,而是给出一些简单的SOAP请求和响应,以便您对
SOAP有一个感性的认识。
假定要用下面的签名调用Web服务中的方法:
intDoSomething(stringstringParam,intintParam)
这条语句必需的SOAP标题和主体如下所示,最上面是Web服务的地址:
POST/SomeLocation/myWebService.asmxHTTP/1.1
Host:
hostname
Content-Type:
text/xml;charset=utf-8
Content-Length:
length
SOAPAction:
"http:
//tempuri.org/DoSomething"
xmlversion="1.0"encoding="utf-8"?
>
Envelopexmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xmlns:
xsd="http:
//www.w3.org/2001/XMLSchema"
xmlns:
soap="http:
//schemas.xmlsoap.org/soap/envelope/">
Body>
//tempuri.org/">
string
int
Body>
Envelope>
length参数用于指定内容的总字节数,它的大小随着string和int参数中发送的值而变化。
Host
也是变化的,它取决于Web服务的位置。
上面代码引用的soap名称空间定义用于构建消息的各种元素。
通过HTTP发送上面的代码时,实
际发送的数据将有所不同(但是相关)。
例如,可以使用简单的GET方法调用上面的方法:
GET/SomeLocation/myWebService.asmx/DoSomething?
stringParam=string&intParam=int
HTTP/1.1
Host:
hostname
这个方法的SOAP响应如下:
HTTP/1.1200OK
Content-Type:
text/xml;charset=utf-8
Content-Length:
length
xmlversion="1.0"encoding="utf-8"?
>
Envelopexmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xmlns:
xsd="http:
//www.w3.org/2001/XMLSchema"
xmlns:
soap="http:
//schemas.xmlsoap.org/soap/envelope/">第55章Web服务和ASP.NET
E241
Body>
//tempuri.org/">
int
Body>
Envelope>
其中length参数的值根据int参数值的变化而改变。
此外,通过HTTP的实际响应也比较简单,例如:
HTTP/1.1200OK
Content-Type:
text/xml;charset=utf-8
Content-Length:
length
xmlversion="1.0"?
>
//tempuri.org/">int
这是一种比较简单的XML格式。
如本节开始时所讨论的,有许多语法问题可以完全忽略。
只有在需要考虑语法时,语法才会变
得很重要。
55.2WSDL
WSDL可以完整地描述Web服务、可用的方法,以及调用这些方法的各种方式。
此外,虽然过
多地讨论WSDL的细节对我们并没有太多的好处,但对WSDL的总体理解却非常有用。
WSDL是另一种与XML完全兼容的语法。
WSDL通过可用的方法、这些方法所使用的类型、
通过各种协议(纯SOAP、HTTPGET等)发送给方法的请求消息和从方法中发送出的响应消息的格
式,以及上面规范的各种绑定,指定Web服务。
WDSL由各种客户端读取,而不只是.NET,还有
本章前言提及的MacromediaFlash。
WSDL文件中最重要的部分或许是类型定义部分。
这一部分使用XML架构描述数据交换的格
式,数据交换的格式要通过可使用的XML元素和元素之间的关系定义。
例如,上一节中的示例所使用的Web服务方法:
intDoSomething(stringstringParam,intintParam)
下面是为请求所做的类型声明:
xmlversion="1.0"encoding="utf-8"?
>
http="http:
//schemas.xmlsoap.org/wsdl/http/"
xmlns:
soap="http:
//schemas.xmlsoap.org/wsdl/soap/"
xmlns:
s="http:
//www.w3.org/2001/XMLSchema"
xmlns:
wsdl="http:
//schemas.xmlsoap.org/wsdl"
...othernamespaces...>
types>
schemaelementFormDefault="qualified"
targetNamespace="http:
//tempuri.org/">
elementname="DoSomething">
complexType>C#高级编程(第7版)
E242
sequence>
elementminOccurs="0"maxOccurs="1"name="stringParam"
type="s:
string"/>
elementminOccurs="1"maxOccurs="1"name="intParam"
type="s:
int"/>
sequence>
complexType>
element>
elementname="DoSomethingResponse">
complexType>
sequence>
elementminOccurs="1"maxOccurs="1"name="DoSomethingResult"
type="s:
int"/>
sequence>
complexType>
element>
schema>
types>
...otherdefinitions...
这些类型都是以前我们看到的SOAP和HTTP请求及响应所必需的,并且这些类型被绑定在文
件中的后期操作上。
所有这些类型都使用标准的XML架构语法指定,例如:
elementname="DoSomethingResponse">
complexType>
sequence>
elementminOccurs="1"maxOccurs="1"name="DoSomethingResult"
type="s:
int"/>
sequence>
complexType>
element>
这个示例指定一个DoSomethingResponse元素,该元素包含一个子元素DoSomethingResult,这
个子元素包含了一个整数。
这个整数必须出现1次,即它必须包含在内。
如果可以访问Web服务的WSDL,就可以使用WSDL。
不久我们可以看到,对WSDL的使用
并不困难。
上面对SOAP和WSDL进行简短的讨论,接下来讨论如何创建和使用Web服务。
55.3Web服务
Web服务的讨论分为两个方面:
●创建Web服务,这一部分主要讨论如何编写Web服务和如何把它们放在Web服务器上。
●使用Web服务,这一部分主要讨论如何在客户端应用程序中使用Web服务。
55.3.1提供Web服务
把代码直接放到.asmx文件中或者从这些文件中引用Web服务类,都可以提供Web服务。
如同
ASP.NET页面一样,在VisualStudio.NET中创建Web服务也使用后一种方法,目的是把问题讲述第55章Web服务和ASP.NET
E243
得更清楚一些。
如图55-1所示,使用File|New|WebSite命令在C:
\ProCSharp\Chapter55目录下创建一个Web服
务项目PCSWebService1,此时系统会生成一组类似的文件,它们与创建Web应用程序项目时所生成
的一组文件相似,其位置选项也相同。
实际上,唯一的区别就是创建Web应用程序时生成的文件是
Default.aspx,而创建Web服务项目时生成的文件是Service.asmx,其代码隐藏是App_Code/Service.cs。
图55-1
Service.asmx中的代码如下所示:
<%@WebServiceLanguage="C#"CodeBehind="~/App_Code/Service.cs"Class="Service"%>
它引用代码文件/App_Code/Service.cs。
下面的程序清单是生成的代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Services;
[WebService(Namespace="http:
//tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
//ToallowthisWebServicetobecalledfromscript,usingASP.NETAJAX,
//uncommentthefollowingline.
//[System.Web.Script.Services.ScriptService]
publicclassService:
System.Web.Services.WebService
{
publicService()
{
//Uncommentthefollowinglineifusingdesignedcomponents
//InitializeComponent();
}
[WebMethod]
publicstringHelloWorld()
{
return"HelloWorld";
}
}
代码段PCSWebService1\App_Code\Service.cs
可从
下载源代码C#高级编程(第7版)
E244
这段代码包含几个标准名称空间引用,并定义Web服务类Service(它在Service.asmx中引用),
Service类继承自System.Web.Services.WebService。
WebService属性指定Web服务的名称空间,它
允许客户端应用程序区分不同Web服务中同名的Web服务方法。
WebServiceBinding属性与Web服
务的交互操作性相关,如WS-IBasicProfile1.1规范中的定义所示。
简言之,这个属性可以声明,
Web服务为一个或多个Web方法支持标准的WSDL描述,或者像这个示例一样,指定一组新的
WDSL定义。
其中还有一个注释掉的ScriptService属性,如果取消注释,就可以使用ASP.NETAJAX
脚本调用Web方法。
现在可以在这个Web服务类上提供其他方法。
在添加可以通过Web服务访问的方法时,只需要把方法定义为public,并给方法提供WebMethod
属性。
这个属性仅把方法标记为可通过Web服务访问。
稍后将会学习返回类型和参数使用的类型,
现在用下面的方法替换自动生成的HelloWorld()方法。
[WebMethod]
publicstringCanWeFixIt()
{
return"Yeswecan!
";
}
现在编译该项目。
要检查是否一切正常工作,可用Ctrl+F5组合键运行应用程序,就会进入Web服务的测试页面,
如图55-2所示。
图55-2第55章Web服务和ASP.NET
E245
在浏览器中显示的大多数文本都说明把Web服务的名称空间设置为http:
//tempuri.org/。
这在开
发过程中不是问题,尽管以后应修改它(如Web页面中的文本所示)。
为此可以使用WebService属性,
但目前可以不修改它。
单击方法名称,可以得到SOAP请求和响应的信息,此外,还可以得到一个示例,说明了如何
通过HTTPGET和HTTPPOST方法获得请求和响应。
另外,也可以单击Invoke按钮,对方法进行
测试。
如果方法需要简单的参数,那么在这个窗体中也可以输入这些参数(如果方法需要较复杂的参
数,这个窗体就不允许以这种方式测试方法)。
这样,就可以看到方法调用所返回的XML:
xmlversion="1.0"encoding="utf-8"?
>
//tempuri.org/">Yeswecan!
这说明方法运行良好。
单击图55-2的浏览器屏幕上的ServiceDescription链接,可以查看Web服务的WSDL描述。
其
中最重要的部分是关于请求和响应的元素类型的描述:
types>
schemaelementFormDefault="qualified"targetNamespace="http:
//tempuri.org/">
elementname="CanWeFixIt">
complexType/>
element>
elementname="CanWeFixItResponse">
complexType>
sequence>
elementminOccurs="0"maxOccurs="1"name="CanWeFixItResult"
type="s:
string"/>
sequence>
complexType>
element>
schema>
types>
该描述文件比较长,除了包含服务的各种绑定之外,还可以包含请求和响应所需类型的描述。
1.对于Web服务可用的类型
Web服务可以用于交换表55-1中所示的类型。
表55-1
StringCharByte
BooleanInt16Int32
Int64UInt16UInt32
UInt64SingleDouble
注意,这个测试页面默认仅可用于本地计算机的调用者,即使Web服务驻留
在IIS(InternetInformationServices,Internet信息服务)中,也是如此。
C#高级编程(第7版)
E246
(续表)
GuidDecimalDateTime
XmlQualifiedNameclassstruct
XmlNodeDataSetenum
以上所有类型的数组都可以使用,因为它们都是泛型集合类型,如List。
还要注意,只
能编组class和struct类型的公共属性和字段。
55.3.2使用Web服务
既然明白了如何创建Web服务,接下来就讨论如何使用它们。
为此需要在代码中生成一个知道
如何与给定Web服务进行通信的代理类。
这样,代码中对Web服务进行的任何调用都要通过这个
代理类,从表面看,这个代理类就等同于Web服务,代码也会认为我们有了Web服务的本地副本。
而实际的情况是有许多HTTP通信工作在进行,只是对我们屏蔽了其中的细节。
有两种方式可以完
成这项任务:
第一,可以使用WSDL.exe命令行工具;第二,可以使用VisualStudio.NET中的Add
WebReference菜单选项。
从命令行中使用WSDL.exe时,它会根据Web服务的WSDL描述生成一个包含代理类的.cs文
件。
使用Web服务的URL来指定该文件,例如:
WSDLhttp:
//localhost:
53679/PCSWebService1/Service.asmx?
WSDL
这样就会在Service.cs文件中为上一节中的示例生成一个代理类。
这个代理类将以Web服务命
名,在这个示例中就是Service,该代理类包含一些方法,那些方法将可以调用与服务同名的方法。
在使用这个类时,只需把所生成的.cs文件添加到项目中,并在代码中使用下面的代码行:
ServicemyService=newService();
stringresult=myService.CanWeFixIt();
默认情况下,生成的类将放在根名称空间中,因此不需要使用using语句,但是,可以使用
WSDL.exe命令行选项/n:
指定一个不同的名称空间。
虽然这项技术非常有效,但是,如果服务正处于开发或处于连续更改中,就比较麻烦。
当然,
为了在每次编译之前自动更新所生成的代理,这项技术可以用项目的构建选项执行,但是我们有更
好的方法。
在一个新的空白网站PCSWebClient1中,为上一节中的示例创建客户端(在C:
\ProCSharp\Chapter55
注意,这里和随后的例子使用默认的文件系统驻留Web应用程序。
为了使上面的
URL起作用,Web服务的VisualWebDeveloperWebServer必须正在运行。
这仍不能
保证Web服务的端口号(在这里是61968)仍相同。
这适合于演示,因为一般我们希望
Web服务驻留在固定的Web服务器(如IIS)上,否则就必须继续重新生成代理类。
确
保Web服务可用于测试的一种方式是在一个解决方案中包含多个Web站点。
第55章Web服务和ASP.NET
E247
目录下),阐明这个更好的方法。
现在创建这个项目,添加Default.aspx页面,并在Default.aspx页面中
添加下面的代码:
LabelRunat="server"ID="resultLabel"/>
ButtonRunat="server"ID="triggerButton"Text="InvokeCanWeFixIt()"/>
代码段PCSWebClient1\Default.aspx