日期:2014-03-19  浏览次数:20429 次

摘要:本文讲解微软ASP.NET Web服务方法(WebMethod)是如何提供高效率的建立Web服务的途径的。WebMethod可以把传统的微软.NET方法暴露为Web服务操作,支持HTTP、XML、XML Schema、SOAP和WSDL。WebMethod(.asmx)处理处理程序能自动地把输入的SOAP消息传递给适当的方法,并自动地把输入的XML元素串行化为相应的.NET对象。

  介绍

  目前在微软.NET中实现基于HTTP的Web服务有两种根本不同的途径。最底层的技术是编写一个插入.NET HTTP管道的自定义IHttpHandler类。这种途径要求你使用System.Web API来处理输入的HTTP消息,使用System.Xml API处理HTTP体中的SOAP封装。编写自定义处理程序要求你手工建立正确描述实现的WSDL文档。严格执行所有的这些操作要求你非常了解XML、XSD、SOAP和WSDL规范,但是这对于大多数开发者来说很困难。

  实现Web服务的效率更高的途径是使用微软ASP.NET WebMethods框架组件。ASP.NET为.asmx终结点(称为WebServiceHandler)发布了一个特定的IHttpHandler类,它提供必要的XML、XSD、SOAP和WSDL功能的范本文件。因为WebMethods框架组件把你从下层XML技术的复杂性中解放了出来,你能够快速聚焦于手头的业务问题。



  图1:灵活性和生产率之间的折衷

  在实现技术之间作出选择形成了图1中所示的灵活性和生产率之间的折衷。编写自定义的IhttpHandler给了你无限大的灵活性,但是要花费你很长时间编写、测试和调试代码。WebMethods框架组件使建立自己的Web服务和快速运行变得很容易,但是很明显你要受到该框架组件界限的限制。但是,在WebMethods框架组件不能提供你完全需要的信息的情况下,可以通过添加自己的附加功能来扩展该框架组件。

  通常,除非你已经掌握了XML、XSD、SOAP和WSDL并且原意承担直接处理它们的负担,最好不要专注于Web服务所需要的WebMethods框架组件。它提供了大多数Web服务端点(endpoints)所需要的基本服务,以及能把框架组件进行"弯曲"来适合你的精确的需要的一些有趣的可扩充能力。本文是基于这种假定讨论WebMethods如何工作的内部信息。如果你不太了解XML Schema和SOAP,可以参阅Understanding XML Schema和Understanding SOAP。

  WebMethods框架组件

  WebMethods框架组件循环地把SOAP消息映射到.NET类中的方法。这种功能的实现首先需要把你的方法注解为System.Web.Services名字空间中的[WebMethod]属性。例如,下面的.NET类包含四个方法,其中两个使用[WebMethod]属性注解了:

using System.Web.Services;public class MathService{   [WebMethod]   public double Add(double x, double y) {      return x + y;   }   [WebMethod]   public double Subtract(double x, double y) {      return x - y;   }   public double Multiply(double x, double y) {      return x * y;   }   public double Divide(double x, double y) {      return x / y;   }}



  为了在WebMethods框架组件重使用这个类,你需要把这个类编译为一个部件(assembly)并把它复制到虚拟目录的bin目录中。在这个例子中,Add和Subtract方法可以被暴露作为Web服务操作,但是Multiply和Divide却不能(因为它们没有使用[WebMethod]标记)。

  你可以通过一个.asmx端点(endpoint)把Add和Subtract暴露为Web服务操作。为了实现这个功能,建立一个名为Math.asmx的包含下面的简单声明的新文本文件,并把它放到包含该部件的虚拟目录中(注意:它自己进入虚拟目录而不是子目录bin中): 

<%@ WebService class="MathService"%>



  这个声明告诉.asmx处理程序使用哪个类检查WebMethods,并且该处理程序自动处理其它的信息。例如,假定虚拟目录叫作"math"并且它包含了Math.asmx,并且bin子目录包含了该部件,那么浏览http://localhost/math/math.asmx将导致.asmx处理程序生成图2所示的文档页面。

  这与.asmx处理程序如何工作有较大的变化。.asmx文件通常只包含通过名字引用Web服务类(如上所示)的WebService声明。因此,在这种情况下,该部件必须已经被编译好、配置到了虚拟目录的bin目录中。.asmx处理程序也提供.asmx文件中源代码的just-in-time(实时)编译。例如,下面的文件(叫作Mathjit.asmx)包含了WebService声明和被引用类的源代码。

<@% WebService class="MathServiceJit" language="C#"%>using System.Web.Services;public class MathServiceJit{   [WebMethod]   public double Add(double x, double y) {      return x + y;   }   [WebMethod]   public double Subtract(double x, double y) {      return x - y;   }   public double Multiply(double x, double y) {      return x * y;   }   public double Divide(double x, double y) {      return x / y;   }}



  第一次通过HTTP访问这个文件时,.asmx处理程序编译源代码并把部件配置到正确的位置。注意WebService声明必须提供语言,这样.asmx处理程序才能在运行时选择正确的编译器。这种方法的一个明显的问题是直到你第一次访问该文件时才会发现编译错误。



  图2:MathService文档

  当你使用Visual Studio .NET建立一个新的Web服务项目时,它通常使用"双文件"技术,把源文件与引用它的.asmx文件分开。集成开发环境(IDE)隐藏了这些文件,但是你可以点击"解决方案浏览器"工具条上的Show All Files(显示所有文件),你会发现项目中的每个Web服务类都有两个文件。实际上,Visual Studio .NET并不支持.asmx文件的高亮度提醒或IntelliSense。有了Web项目后,Visual Studio .NET也处理建立虚拟目录并自动把部件编译到虚拟目录的bin目录中。

  在深入分析.asmx处理程序如何工作前,我们先简短讨论一下来自IIS的消息如何分派到用于处理的.asmx处理程序中。当输入的HTTP消息到达80端口时,IIS使用自己的元数据库(metabase)的信息来找出使用哪一个ISAPI DLL来处理这个消息。.NET安装程序把.asmx