分享
 
 
 

利用微软Atlas消费外部Web服务

王朝other·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

摘要 为了从Atlas中消费外部Web服务,你可以为这些服务构建一个基于服务器的Web服务代理。幸好,你可以利用Visual Studio和Atlas特征来处理这其中的大部分工作。

一、引言

如今,Ajax已经成为构建基于浏览器的交互式客户端应用程序的主流技术,从而使得服务器端行为集中于提供特定的Web服务。另一方面,Web服务已经成为当今在服务器级暴露业务功能的事实上的标准。假定如此,那么出现一个核心开发问题:如何使你的基于AJAX的应用程序与Web服务进行通讯?本文正是想同你一起探讨如何使用微软Atlas(最近,又命名为asp.net AJAX)来实现这一目的。

首先,你需要使用Visual Studio 2005,并且需要下载和安装微软Atlas。假如你没有安装Visual Studio 2005,那么你可以下载一个免费的Visual Studio EXPRess版本。本文将使用一个ZipCodeRUs示例应用程序来解释如何通过Atlas实现该程序与Web服务的交互。这个示例应用程序能够检索具体的邮政代码信息,例如城市、县的名称及其纬度、经度等信息。该程序依靠于tilisoft.com网站提供的一个免费且公开可用的Web服务来检索该信息。这个示例应用程序从下面两个角度展示了Atlas的Web服务威力:

· 展示了Atlas的javascript代理,这个代理能够与一个ASP.NET(.asmx)Web服务(该服务担当到外部Tilisoft ZIP代码Web服务的"沟通"桥梁)进行异步地通讯。

· 还展示Atlas从Javascript客户端成批地调用服务器端web服务的能力。

【作者注】 微软Atlas还支持创建到外部Web服务的基于xml的声明性桥接而不必创建上面的所谓"沟通"服务;不过,本文并没有涉及有关这个桥接特征的讨论。

二、Atlas Web服务入门

打开Visual Studio,通过选择如图1所示的"Atlas"Web Site模板创建一个新的Web应用程序"ZipCodeRUs"。该"Atlas"Web Site模板是当你下载并安装微软Atlas CTP时安装的。基于这个"Atlas"Web Site模板创建的网站中会自动包含对Microsoft.Web.Atlas.dll的一个引用;还包括一个Web.config文件,该文件为网站使用Atlas技术作好了预配置。

图1.创建一个新的Atlas Web应用程序:当你安装微软Atlas CTP后,你会在"New Web Site"对话框中看到一个新的称为"Atlas"Web Site的工程模板。

与依靠于外部Web服务(服务不是在与应用程序本身相同的域内提供)的AJAX应用程序相关的一个常见的问题是,你不能够使用JavaScript来直接存取这样的Web服务-浏览器将阻止所有这样的"cross-scripting"存取。由于安全原因,浏览器仅仅答应一个Web页面中的JavaScript存取最初创建该页面的网站。为了解决这个问题,Atlas JavaScript客户端依靠于.asmx文件(ASP.NET Web服务)来创建运行时刻JavaScript代理。换句话说,客户端先调用一个由home(本地)域所暴露的Web服务,然后由这个服务再调用外部Web服务,最后简单地把响应传送回客户端。

因此,在你能够从你的Atlas客户端调用一个外部Web服务前,你首先需要创建一个强类型化代理。在这个示例中,我为Zip代码Web服务构建了一个C#代理,其中还创建了一个ASP.NET Web服务,它用作一个上面的"沟通桥梁"。

三、 创建一个代理客户类

存在两种创建Web服务客户端代理类的方法。你可以在Visual Studio命令行上使用wsdl.exe来创建这些代理类;或者从Visual Studio IDE中创建一个Web引用。下面命令展示了如何从你的应用程序的App_Code文件夹下使用wsdl.exe来为ZipCode Web服务创建强类型化代理类。注重,当你从命令行输入下列代码时,下面这些内容应该在同一行上。

C:\projects\ZipCodeRUS\App_code> wsdl.exe

http://www.tilisoft.com/ws/LocInfo/ZipCode.asmx?WSDL

/namespace:Tilisoft.ZipCode

上面的命令将创建一个ZipCode.cs文件,它包含一个你能够在你的本地的代码中使用的TiliSoft.ZipCode代理类。

接下来,你需要创建上面起"沟通桥梁"作用的Web服务。右击Solution Explorer中的最上面一层,并从弹出菜单中选择"Add New Item…"选项,然后选择Web服务模板。我把该服务命名为"ZipCodeConduitService"。

这个ZipCodeConduitService服务中只提供了一个称为GetZipCodeInfo的函数。它使用两个字符串参数:一个字符串correlationID,一个ZIP代码。当被调用时,该服务使用生成的代理类以便TiliSoft Web服务检索特定数据,最后,把这些结果传递回ZipCodeConduitData应用程序。为了演示Atlas的异常处理能力,我添加了一个"小拐弯":假如用户输入的ZIP代码是"错误",那么GetZipCodeInfo()将抛出一个ZipCodeConduitException异常。下面是相应于ZipCodeConduitService Web服务类的代码:

...

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class ZipCodeConduitService : System.Web.Services.WebService{

...

[WebMethod]

public ZipCodeConduitData GetZipCodeInfo(String corelationId,String zipCode) {

if (zipCode.Equals("error")){

throw new ZipCodeConduitException(corelationId,"Here is an error just for you!! Enjoy!");

}

ZipCode xZipCodeService = new ZipCode();

ZipCodeConduitData zipCodeConduitData = null;

ZipCodeData xZipCodeData = xZipCodeService.GetInfo(zipCode);

zipCodeConduitData = new ZipCodeConduitData(corelationId, zipCode, xZipCodeData);

return zipCodeConduitData;

}

}

在前面的代码中,ZipCodeConduitData是一个值对象,用于在客户端和ZipCodeConduitService之间传递信息。这个ZipCodeConduitData类具有如下所示的get属性,而CorelationId属性答应客户端跟踪它们的请求。

...

using Tilisoft.ZipCode;

public class ZipCodeConduitData{

public ZipCodeConduitData(String corelationId,ZipCodeData data) {

hydrate(corelationId, data);

}

String _corelationId;

public String CorelationId{

get { return _corelationId; }

}

...

String _county;

public String County{

get { return _county; }

}

String _city;

public String City{

get { return _city; }

}

...

private void hydrate(String corelationId, ZipCodeData data) {

_corelationId = corelationId;

if (data.ZipCodeInfo.Count > 0) {

_zipCode = data.ZipCodeInfo[0].ZIPCODE;

_county = data.ZipCodeInfo[0].COUNTY;

_city = data.ZipCodeInfo[0].CITY;

...

}

}

}

这个ZipCodeConduitException是一个派生自System.Exception的C#异常类。该异常类包括correlationId值;客户端在每次发送请求时都使用它,详见下面的代码片断:

...

using System;

...

public class ZipCodeConduitException : System.Exception{

String _corelationId;

public String CorelationId{

get { return _corelationId; }

set { _corelationId = value; }

}

public ZipCodeConduitException(String corelationId, String message):base(message) {

_corelationId = corelationId;

}

}

QQRead.com 推出数据恢复指南教程 数据恢复指南教程

数据恢复故障解析

常用数据恢复方案

硬盘数据恢复教程

数据保护方法

数据恢复软件

专业数据恢复服务指南

四、 构建ZipCode JavaScript客户端

现在,既然你已经实现了服务器端的Web服务代码,那么接下来,你可以创建一个存取该服务的JavaScript客户端。为此,你要添加ZipCodeConduitClient.aspx;这是通过使用"Add New Item…"→"Web Form"选项来把一个Web表单添加到你的ZipCodeRUs中实现的。

在ZipCodeConduitClient.aspx代码中,通过创建Atlas的ScriptManager的一个实例并且把一个对基于ASP.NET的Web服务ZipCodeConduitService.asmx文件的引用添加到Web页面的元素来启动微软Atlas。详见下面的代码:

...

<head id="Head1" runat="server">

<title>Zip Code Information Service - Atlas JavaScript Conduit

Client</title>

<atlas:ScriptManager ID="scriptManager" runat="server"

EnableScriptComponents="true">

<Services>

<atlas:ServiceReference

Path="ZipCodeConduitService.asmx" />

</Services>

</atlas:ScriptManager>

<script type="text/xml-script">

<page xmlns:script=

"http://schemas.microsoft.com/xml-script/2005">

<components>

<webRequestManager batchSize="5"

enableBatching="true" batchDelay="3000" />

</components>

</page>

</script>

</head>

...

有趣的是,前面的代码支持在JavaScript和Web服务之间的"批"方式的Web服务请求。通过添加webRequestManager元素以及把enableBatching属性值设置为true可以使得由Atlas来承担所有的繁重工作-积累所有的请求,然后在一个批中立即执行它们。Atlas还能够跟踪所有的返回值和来自于Web服务中的对象。注重,上面的代码能够"积累"达到五个请求,然后一次性执行所有的请求。

现在,你可以通过添加一些Html和ASP元素来创建web页面上的可视化元素。最终产生的页面大致如图2所示。

图2.该图展示了Visual Studio中处于设计方式的ZipCodeConduitClient.aspx页面。

...

<form id="ZipCodeConduitClient" runat="server" ></form>

<h4>

Enter ZipCodes: 1> <input id="textZipCode1" />

2> <input id="textZipCode2" />

3> <input id="textZipCode3" />

<input id="buttonZipCode" type="button"

value="Get Information"

onclick="return OnbuttonZipCode_click()" />

</h4>

<table border="1" cellpadding="5" cellspacing="2">

<tr>

<td></td>

<td><asp:Label ID="corelationId1" runat="server"

Text="."/></td>

<td><asp:Label ID="corelationId2" runat="server"

Text="."/></td>

<td><asp:Label ID="corelationId3" runat="server"

Text="."/></td>

</tr>

<tr>

<td>ZipCode</td>

<td><asp:Label ID="zipCode1" runat="server"

Text="."/></td>

<td><asp:Label ID="zipCode2" runat="server"

Text="."/></td>

<td><asp:Label ID="zipCode3" runat="server"

Text="."/></td>

</tr>

...

<tr>

<td></td>

<td><asp:Label id="message1" runat="server"

Text="."/></td>

<td><asp:Label id="message2" runat="server"

Text="."/></td>

<td><asp:Label id="message3" runat="server" Text="."/></td>

</tr>

</table>

<asp:Label ID="message" runat="server" BorderStyle="Groove"

BackColor="#FF8080" BorderWidth="1px" Font-Bold="True"

ForeColor="White">Ready</asp:Label>

...

注重,在此,"Get Information"(在源代码中命名为buttonZipCode)按钮的点击导致调用OnbuttonZipCode_click() JavaScript函数,请参考下面的代码:

<script type="text/javascript" language="JavaScript">

function OnbuttonZipCode_click()

{

document.getElementById('message').innerHTML = "Retrieving Information...";

if (document.getElementById('textZipCode1').value.length > 0)

{

service = ZipCodeConduitService.GetZipCodeInfo("1", document.getElementById('textZipCode1').value,

OnComplete, //完成事件

OnTimeout, //超时事件

OnError // 出错事件

);

}

...

}

return false;

}

...

</script>

在这个OnbuttonZipCode_click函数中,ZipCodeConduitService JavaScript代理对象可以为Atlas所隐含地使用。注重,GetZipCodeInfo()函数共使用三个参数,除了在ZipCodeConduitService Web服务中GetZipCodeInfo()函数所使用的两个参数以外。这是因为Atlas使所有的Web服务调用都以异步地进行;在发出一个Web服务调用后,JavaScript客户端代码并不等待该服务器的响应。当响应到达时,Atlas框架需要使用客户端的一个回调函数。GetZipCodeInfo方法使用的其它参数正是从JavaScript代码指向这些回调函数的指针。来自于服务器的响应可能是成功的,可能是返回一个错误消息,也可能是因超时而无响应返回。前面的代码分别由OnComplete(),OnError()和OnTimeout()函数负责处理每一种可能的响应类型。

QQRead.com 推出数据恢复指南教程 数据恢复指南教程

数据恢复故障解析

常用数据恢复方案

硬盘数据恢复教程

数据保护方法

数据恢复软件

专业数据恢复服务指南

下面代码列出了这些函数。这些函数都接收一个result参数,其中包含服务器返回的响应。在此情况下,ZipCodeConduitService把一个ZipCodeConduitData类的实例返回给OnComplete()函数,而把一个ZipCodeConduitException异常返回给OnError()函数。

...

function OnComplete(result) {

document.getElementById('message').innerHTML = "Ready";

if (result.CorelationId == '1') {

document.getElementById('corelationId1').innerHTML = result.CorelationId;

...

document.getElementById('message1').innerHTML =

result.Message;

}

else if (result.CorelationId == '2') {

...

}

else if (result.CorelationId == '3') {

...

}

}

function OnError(result) {

displayMessage(result);

}

function OnTimeout(result) {

document.getElementById('message').innerHTML = "Request Timeout";

}

function displayMessage(result) {

if (result.CorelationId == '1') {

document.getElementById('message1').innerHTML = result.get_message();

}

...

}

</script>

五、运行结果

至此,服务器端与客户端代码都已到位。在Visual Studio中以debug方式启动ZipCodeConduitClient.aspx或把你的应用程序发布到一个网站;然后,试着输入三个ZIP代码来检索关于这三个ZIP代码的细节,请参考下面图3。

图3.ZipCodeConduitClient运行中:这是在一个Web浏览器中运行ZipCodeConduitClient.aspx页面并显示检索三个ZIP代码的结果。

六、小结

如今,AJAX使得开发交互性的Web应用程序进一步简单化;而现在微软也已经着手简化从支持AJAX技术的客户端应用程序中调用Web服务的过程。随着AJAX技术进一步融入主流开发中,我们完全可以期望微软把Atlas更为紧密地集成到Visual Studio中及其它微软开发平台和产品中。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有