| 网站首页 | VB.Net实例分析 | .Net技术文摘 | 下载中心 | VB.Net书籍笔记 | .Net源码 | VBS脚本与组件调用 | Windows2008技术文摘 | 给我们留言 | 
最新公告:

  没有公告

您现在的位置: 乐博网 >> VB.Net书籍笔记 >> 网站编程 >> VB.Net书籍笔记正文
最新推荐 更多内容
[组图]Ajax与.NET 2.0高级程序设计(2)           ★★★
Ajax与.NET 2.0高级程序设计(2)
作者:Daniel W… 文章来源:Ajax与.NET 2.0高级程序设计 点击数: 更新时间:2007-11-4

        几年前,Web服务曾风靡一时。微软公司、Sun公司还有其他许多公司都鼓吹它是在线通信的下一件大事。说实话,我多少还是被他们唬住了。恐怕那些个简称就会吓倒我,技术术语满天飞:SOAP、XML、REST、WSDL以及DISCO。我一度认为任何具有很多术语简称的东西可能都是非常急需又难学的。我知道如果微软公司也在推行它,我最后也将不得不被拉下水。后来,我很惊喜并且轻松地发现,这门技术并不难,而且Visual Studio已将大部分接口封装进一个易于使用的项目模板之中了。

适应了新技术就会爱上它,对Web服务也不例外。你可以立志成为一个使用SOAP、创建WSDL的Web服务大师,也可以选择就做一个快捷和易用的ASP.NET Web服务项目。基于本书的目的,我们将采取后一种方式。这项技术本身可以很复杂,但是我们应该对Ajax更关注一些,所以我们要尽量减少不必要的负担。你可从其他书籍中去了解更多ASP.NET Web服务的知识。

9.1  什么是Web服务

如果你对创建或利用ASP.NET 2.0 Web服务几乎没有什么印象和知识,你可能需要首先阅读这一节。否则,你尽管跳过这一节向前阅读。

因特网Web服务其实就是在Web上进行数据交换的一种方法。 其真正酷的部分在于服务提供者是平台独立的。我们假设Joe Johnson想要在其汽车零件零售网上加一个在线零件查找的Web服务。Joe只会Java,他的知识足够用来设置一个Web服务。

他的网友Bob也要一起行动,他想在他的汽车收藏家站点建立一个访问入口,供用户查找稀少的和已停产零件的服务。然而Bob却只懂得ASP.NET而不懂Java。那么Bob的汽车收藏站点是否仍然可以从Joe的零件门户检索数据呢?是的,它可以。因为Web服务的魅力就在于,能够以纯XML文本方式进行通信。通过众所周知的SOAP(Simple Object Access Protocol,简单对象存取协议)信封,这些文本信息以一种模糊的方式传递请求和响应文本。

9.2  SOAP

SOAP是结构化数据,因此类似于我们已经使用过的一些数据格式。在此我们只看一看它的数据格式和用法,不会深入到SOAP中去。

我们前面讨论过,SOAP是一种XML方言。这个包亦称SOAP信封。如你所料,该信封负责包含将要跨Web进行传输的数据。在每个独立的信封内,是大多数标准的HTTP通信都有的首部和主体两部分。通常,你通过HTTP POST与目的地之间收发SOAP信封。所以在消息内也将包括HTTP指令。请注意,POST请求不全是XML的,包含的SOAP包才是。

我们再来看一下前面的例子。Johnson的汽车零件网站有一个在线Web服务,提供多个方法让我们可以访问不同的零件数量、价格以及库存情况。Bob对GetQuantity方法特别感兴趣,因为他已经有了零件号码,刚好想要看看Joe是否有库存。Bob需要提交一个SOAP消息到该Web服务来请求数量。他的请求类似于:

 

Joe网站中的基于Java的Web服务接收到这个消息,查找数据,然后返回下列SOAP响应:

显然,这并不是来自一个真正的Web服务,因为你可以看到默认名字空间和缺少实际数据。但是它说明了SOAP具有请求和响应的HTTP功能。注意,响应中的200状态,这指示调用是成功的。还须注意到,Joe的Web服务采取原文消息并且把Response和Result连接到来自Bob的消息提交中的相应的调用。 

使用SOAP消息还可以做许许多多的事情,但这些不在本书的讨论范围内。幸运的是,只要在Visual Studio开发环境之内,我们实际上不必使用SOAP做任何事情。它将通过Web服务代理为我们生成所有这些信封,我们只需关注于构建和利用Web服务。 

9.3  对Ajax的影响

那么这对于Ajax意味着什么呢?意味着两件事情。后面的演示说明,我们仍能以类似访问数据库的方式从一个异步过程中访问Web服务调用。此外,当我们迁移或者平移到微软的Atlas平台时,我们将能够直接地从客户端代码调用Web服务。

实际上,可以用XmlHttpRequest调用Web服务、解析SOAP消息以及使用数据,但是我们还是集中利用现在可以使用的Ajax库。我在前面说过,要注意及时了解各种可用的库的更新;敢肯定它最终会提供这样的功能。但是现在,我们以多层方法来进行,并且将我们的服务调用保持在服务器端。

9.4  创建Web服务

现在可以继续前行,创建一个我们将发布的Web服务并且使它能被我们的Ajax应用访问。

启动Visual Studio2005,然后选择File→New→Web Site。

当提示你选择项目类型的时候,单击ASP.NET Web Service。单击OK之前,我们需要对这个特别的窗口做一些修改。因为我们正在构建一个Web服务,所以应该使IIS可以访问它。在位置下拉列表,选择HTTP。应注意到,出现了一些新的选项如图9-1所示。

图9-1  创建HTTP Web服务

单击Browse将出现一个新的窗口。我们创建一个虚拟目录来驻留Web服务并且给它一个在计算机上的固定的位置。

选择左边的IIS,然后选择Creat New Web Application,如图9-2所示。

图9-2  创建IIS应用

把应用命名为wsAdventureWorks,然后单击OK。

再回到New Web Site窗口,选择OK,让Visual Studio构建项目(最终)。

解决方案应该看上去非常类似于图9-3的样子。

图9-3  wsAdventureWorks解决方案的文件

终于可以开始编写一些代码了。首先来看看.cs文件。它有一些默认的名字空间,应该对其进行修改。你不必使用一个真实的站点,因为它们实际上只是用来进行数据区分。让你的名字空间采用一个恰当的名字模式,就可以避免与其他已经发布的Web服务冲突。

如果使用了预先设计好的组件InitializeComponent(),那么就不对下列行进行注释。

 

现在先不要管HelloWorld方法。我们马上会修改它。

保存你的项目,免得机器发生故障时工作尽失。 

现在我们有了一个通用的Web服务,可以添加一些功能到其中了。但是我们想要它做点什么呢?在前面的数据查找之后模拟Web服务,并且提供一个简单的参数/查找数据库查询。AdventureWorks数据库有一个Production.Product表,其中有大量的产品数据。我们将构建一个Web服务,它返回定价等于或小于我们给出的参数值的产品的数据集。我们将实现一个WebMethod来根据当前价格有限制地返回产品列表。修改Service.cs 如下: 

得到价格小于等于参数的产品。

 

如果使用了预先设计好的组件InitializeComponent(),那么就不对下列行进行注释。

 

在构建和试验Web服务之前,如果使用SSPI安全的话,你需要检验ASPNET用户账户具有对AdventureWorks数据库的访问权限。

把上述代码加到你的.cs文件中,然后保存。

现在来看一下Web服务的调用进程。Visual Studio最酷的特征是你在将Web服务发布之前可以对其进行展示。它是一个相当直接的过程,并且你将发现该界面很容易使用。

在Visual Studio中启动你的项目。稍顷,IE将向你展示如图9-4的屏幕。

测试界面再次向我们展示了被调用的服务可以访问的Web方法。在这里,我们只有一个方法:GetProducts。通过在代码中的函数名前加上WebMethod属性,可以使得该函数在代码中能够访问。

为了演示这个功能,在与Web服务交互时只需单击超链接然后等待,如图9-5所示。

图9-4  测试你的服务

图9-5  添加参数

我们为调用提供参数并且单击Invoke按钮。结果通过XML返回给我们,如图9-6所示。

图9-6  Web服务结果

你可以对结果进行翻滚查看,我们返回了很多信息。我们可以细化SQL字符串,以将结果削减为几个字段,但是暂时先不这么做。现在,请继续进行,停止调试应用并且关闭Visual Studio 2005。

9.4.1  构建Ajax应用

现在已经有了一个Web服务运行在IIS上,我们继续Web服务实现。我们将通过构建一个简单的客户程序,由它来访问Web服务并且返回结果。

像前面一样,启动Visual Studio 2005并且创建一个新的ASP.NET网站。不要忘记把你的Location设回为File System,如图9-7所示。

图9-7  创建一个新网站

在Visual Studio准备好项目文件之后,我们需要添加一个Web引用,以便可以通过代码访问Web服务。右击项目名,并且选择Add Web Reference,如图9-8所示。

图9-8  添加Web引用

系统提示你浏览Web服务。你可以单击Local Machine链接上的Web Services。应用程序将花点儿时间来查找你的计算机上正在运行的Web服务。一会儿工夫之后,它将向你展示已经在IIS之上运行的所有服务。

你应该能够看到你的服务以wsAdventureWorks的名称列出。单击Service链接,你将访问到一个熟悉的页面,其中列出了可用的方法,如你在前面测试该Web服务时所见。我们需要修改该Web引用名称为图9-9所示的内容。 

在修改名称之后,单击Add Reference按钮。Web服务现在将被添加到项目的引用列表中。此外你还将注意到Visual Studio添加了几个额外的文件:Service.disco、Service.discomap以及Service.wsdl。 

图9-9  添加引用

Service.disco和Service.discomap文件帮助外部资源定位Web服务,Service.wsdl描述该Web服务能做什么。

我们首先来构建一个用户界面,以此开始通过代码使用新的Web服务,如图9-10所示。

图9-10  客户界面

本例我们仅仅需要文本、文本框以及按钮。修改Default.aspx代码如下:

这里的大部分代码你应该非常熟悉,因为它们和前一章的演示应用程序非常相似。我们有两个调用和回调JavaScript函数,它们作为按钮的onclick事件的结果到达服务器端。文本是通过响应对象生成和返回的,并且将要发出给div标签的innerHTML。

我们来看一下怎样和服务器端的Web服务通信:

不要忘记注册你的页面。

 

我们将返回HTML表格给客户端的innerHTML属性。

 

通过表行进行迭代,建立一个HTML表。

 

现在将Web服务的输出赋值给我们的数据集。

 

创建Web服务的新实例。

 

在这个示例应用中,我们仅仅有一个Ajax方法,它主要用于调用Web服务方法并且操纵结果。

我们必须首先实例化Web服务:

然后调用GetProducts方法:

一旦数据被返回,我们只需要解析它,构建一个HTML表格。该表格然后被返回到客户端的回调函数,在那里被指派给divResults的innerHTML属性。

如果运行该应用,会被要求输入一个数量。假设输入125并且单击Go!按钮,结果将会被Web服务异步取回,并且按我们期望的方式显示出来(参见图9-11)。

图9-11  异步Web服务应用

这样就完成了这个例子。我们已经构建了一个Ajax应用程序,它可以异步地访问Web服务。在这个应用程序和实现同样功能的Ajax库的数据库应用程序之间的确有一点点不同。我们只不过是将Ajax方法内容指向一个因特网Web服务而不是一个数据存储。 

9.4.2  通过XmlHttpRequest访问

此时你可能会问“如果我想要从客户端访问一个Web服务该如何办呢?”如前所述,除了Atlas以外,大多数的现代Ajax库还没有具有一个客户端访问的实现。但可以使用XmlHttpRequest对象来与那个讨厌的Web服务通信。作为开发者,我们将不得不编写代码来解析入站和出站XML,但这已经超出了Ajax库自如控制的范围。但是这是可以完成的,下面我就向你展示可以如何进行。

使用来自前面的例子的同一个站点(即我们刚刚完成的那个)。右击该项目名并且选择Add New Item。我们将添加一个新的Web表单,命名它为xhrAccess.aspx,如图9-12所示。

图9-12  添加新表单

因为我们将使用JavaScript来完成任务,所以不需注册任何Ajax库组件。事实上,我们将根本不使用任何库。

我们将借鉴上一章的代码,你可以从相应的章节示例代码中复制和粘贴过来,而不用照书上的代码重新输入。

要和Web服务通信仅需使用XmlHttpRequest对象,我们的应用程序需要完成下列这些事情:

q 实例化一个跨浏览器平台的XmlHttpRequest对象。

q 创建一个SOAP信封以供传输。

q 在客户端解析XML-SOAP结果。

q 在客户端上显示解析过的XML。

来看一下完整的.aspx代码,然后我将详细地描述各个部分:

现在尝试IE实现。

 

首先尝试遗留对象。

 

现在构建SOAP信封。

 

实例化XmlHttpRequest对象getHTTPRequestObject()。

首先得到文本框值。

 

我们必须使用基于Mozilla的浏览器,所以现在创建一个本地请求对象。

 

分配回调函数。

 

创建XML对象。

 

上面的HTML以和前面的演示程序一样的方式建立了用户界面(参见图9-13)。

图9-13  用户界面

按钮的onclick事件启动了GetProductsList()函数,并且最终导致XmlHttpRequest对象的创建。我们需要一个能够创建跨浏览器支持的对象的函数:

我们必定在使用一个基于Mozilla的浏览器,所以现在创建一个本地请求对象。

 

现在尝试IE实现。

 

首先尝试遗留对象。

 

这个特别的过程你应该已经很熟悉了,因为在第3章已经见过它了。我们简单地根据客户端的浏览器实例化了XmlHttpRequest对象,并且指定它给一个页面级的变量。一旦完成这个工作,我们将具有异步调用Web服务所需的全部功能。

我们需要针对Web服务位置和名字空间的占位符,因为我们还要指定它们到我们传递的消息中:

因为我们是在调用Web服务,所以我们将需要手工创建一个SOAP信封。这并没想象中的那样困难。在Visual Studio中创建它之后再运行Web服务的时候,测试工具程序实际上已经提示了我们可以怎样创建SOAP POST,如图9-14所示。

如你所见,SOAP消息的XML构造已经列出来了。我们将根据这个消息来构造信封。

我们构建SOAP信封如下所示: 

现在构建SOAP信封。

 

图9-14  Web服务测试工具

正如你所看到的,我们根据在文本字段中找到的值,动态地指定MaxAmount参数值给SOAP信封主体:

我们需要告诉XmlHttpRequest对象,在对象请求状态完成之后,需要使用哪一个函数来处理返回值:

稍后讨论processResults ()函数,但是我们首先必须指定不同的POST属性并且按计划发送异步调用:

SOAP包将按其路线传输到Web服务,调用适当的方法,并返回串行化的DataSet。如果MaxAmount为4,结果如图9-15所示。 

图9-15  完整的XML结果

我们将在客户端的回调函数之内接收到这个信息:

创建XML对象。

 

DataSet如期返回客户端,但是因为它的串行化状态,我们还无法在浏览器之中对它作过多处理。我们将需要调用ParseDataSet()函数来解析数据。在该函数内部,我们将迭代所有XML结点,构建一个HTML表格来指派给div的innerHTML属性:

所有的Ajax功能都是在客户端处理的。服务器端代码基本没有什么内容:

这里只有一个空的命令解释程序。

 

运行这个应用之后,我们发现其输出几乎和前面编写的ASP.NET服务器端应用的输出一致,如图9-16所示。

图9-16  通过XmlHttpRequest调用Web服务

对的,它们看起来几乎一样。我们的List Price列没有像.NET版本一样显示成标准化的货币格式。在我们能够调用String.Format函数之前,请注意我们现在使用的是JavaScript,并且必须使用一个定制的函数来完成那个格式化:

只需要修改表格行构建器,以便List Price列的所有行都能够被格式化。

 

现在我们的结果和本章前面的.NET服务器端应用一致了,如图9-17所示:

图9-17  经过格式化的List Price列

9.5  小结

我们仅仅通过XmlHttpRequest对象,就成功地访问了Web服务。如果你见过SOAP信封的各种解析和扰乱问题,也许你就能理解为什么我之前曾经说过,从服务器端代码访问Web服务比起手工构造客户端函数来访问要容易得多。通过Web服务功能实现Ajax方法真是容易至极,并且可以很快地上手。

在下面的几章,我们将继续使用Ajax库,构建更多示例应用,从中可以得到实施到其他Ajax项目中的珍贵的信息。 

  • 上一篇: 没有了

  • 下一篇: 没有了
  • 【字体: 】【打印此文】【关闭窗口
      相关文章:
    Ajax与.NET 2.0高级程序设计(3)
    Ajax与.NET 2.0高级程序设计(1)

    | 设为首页 | 加入收藏 | 联系站长 | | 友情链接 | 版权申明 |
    乐博网欢迎各种媒体转载我们的原创作品[转载请注明出处];我们鼓励更多VB.Net开发者一起加入研究与探讨;如发现文章访问错误、内容错误或版权疑问、内容有违相关法律(如涉及政治、色情、反动或散布虚假有害信息)等情况,请及时向我们举报,我们将及时纠正!
    联系邮箱:Shiny#vip.qq.com (#替换为@) QQ交流群: 40797788 [闽ICP备05014267号]