在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(Yahoo!天气实例)...

作者:Dflying Chen ( http://dflying.cnblogs.com/

在前一篇文章(在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(基础知识以及简单示例))中,我介绍了一些Atlas中对远程Web Service进行Mashup的基础知识,并给出了一个最基础的没有丝毫用处例子。今天再回到这个话题上,我将给出一个更复杂点的,但有一些用处的例子——Yahoo! Weather。

废话到此为止,让我们先熟悉一下Yahoo! Weather服务:Yahoo!在其网站上提供了天气预报服务(http://weather.yahoo.com/),并且它也提供了Web Service的接口(http://developer.yahoo.com/weather/
从上面两个网页上面,我们可以知道Yahoo!提供的天气Service的URL为http://xml.weather.yahoo.com/forecastrss,该服务还有两个参数:

  1. p:要查询天气的地点代码(可以在http://weather.yahoo.com/查询到不同地方的这个代码)。
  2. u:返回结果中温度的单位,f代表华氏度,c代表摄氏度。

看来这个Yahoo! Weather服务还挺简单的,让我们测试下好不好用。先到http://weather.yahoo.com/查出来上海的地点代码为CHXX0116。然后在浏览器中输入http://xml.weather.yahoo.com/forecastrss?p=CHXX0116&u=c,嗯,返回了如下的一段不是很复杂的XML:

ContractedBlock.gif ExpandedBlockStart.gif Yahoo Weather Service XML Result
None.gif<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
None.gif
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
None.gif  
<channel>
None.gif    
<title>Yahoo! Weather - Shanghai, CH</title>
None.gif    
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Shanghai__CH/*http://xml.weather.yahoo.com/forecast/CHXX0116_c.html</link>
None.gif    
<description>Yahoo! Weather for Shanghai, CH</description>
None.gif    
<language>en-us</language>
None.gif    
<lastBuildDate>Thu, 25 May 2006 11:00 am CST</lastBuildDate>
None.gif    
<ttl>60</ttl>
None.gif    
<yweather:location city="Shanghai" region="" country="CH" />
None.gif    
<yweather:units temperature="C" distance="km" pressure="mb" speed="kph" />
None.gif    
<yweather:wind chill="21" direction="260" speed="14" />
None.gif    
<yweather:atmosphere humidity="78" visibility="299" pressure="0" rising="0" />
None.gif    
<yweather:astronomy sunrise="4:52 am" sunset="6:50 pm" />
None.gif    
<image>
None.gif      
<title>Yahoo! Weather</title>
None.gif      
<width>142</width>
None.gif      
<height>18</height>
None.gif      
<link>http://weather.yahoo.com/</link>
None.gif      
<url>http://us.i1.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url>
None.gif    
</image>
None.gif    
<item>
None.gif      
<title>Conditions for Shanghai, CH at 11:00 am CST</title>
None.gif      
<geo:lat>31.17</geo:lat>
None.gif      
<geo:long>121.43</geo:long>
None.gif      
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Shanghai__CH/*http://xml.weather.yahoo.com/forecast/CHXX0116_c.html</link>
None.gif      
<pubDate>Thu, 25 May 2006 11:00 am CST</pubDate>
None.gif      
<yweather:condition text="Fog" code="20" temp="21" date="Thu, 25 May 2006 11:00 am CST" />
None.gif      
<description>
None.gif        
<![CDATA[
None.gif          <img src="http://us.i1.yimg.com/us.yimg.com/i/us/we/52/20.gif" /><br />
None.gif           <b>Current Conditions:</b><br />
None.gif           Fog, 21 C<BR /><BR />
None.gif           <b>Forecast:</b><BR />
None.gif            Thu - Scattered Thunderstorms. High: 25 Low: 20<br />
None.gif            Fri - AM Showers. High: 26 Low: 18<br />
None.gif           <br />
None.gif          <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Shanghai__CH/*http://xml.weather.yahoo.com/forecast/CHXX0116_c.html">Full Forecast at Yahoo! Weather</a><BR/>
None.gif           (provided by The Weather Channel)<br/>
None.gif         
]]>
None.gif      
</description>
None.gif      
<yweather:forecast day="Thu" date="25 May 2006" low="20" high="25" text="Scattered Thunderstorms" code="38" />
None.gif      
<yweather:forecast day="Fri" date="26 May 2006" low="18" high="26" text="AM Showers" code="39" />
None.gif      
<guid isPermaLink="false">CHXX0116_2006_05_25_11_0_CST</guid>
None.gif    
</item>
None.gif  
</channel>
None.gif
</rss>
None.gif
<!-- p1.weather.scd.yahoo.com uncompressed/chunked Thu May 25 20:49:07 PDT 2006 -->

我们可以看到,它提供的信息非常全面(连日出日落时间都有……),下面让我们书写asbx Bridge页面来对这个Service进行Mashup。

首先,参考在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(基础知识以及简单示例)这篇文章中的那个asbx的声明,我们可以写出如下一段:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< bridge  namespace ="Dflying"  className ="YahooWeatherService" >
None.gif
None.gif  
< proxy  type ="Microsoft.Web.Services.BridgeRestProxy"  
None.gif         serviceUrl
="http://xml.weather.yahoo.com/forecastrss"   />
None.gif
None.gif  
< method  name ="GetWeather" >
None.gif    
< input >
None.gif      
< parameter  name ="p"   />
None.gif      
< parameter  name ="u"  value ="c"   />
None.gif    
</ input >
None.gif  
</ method >
None.gif
</ bridge >

其中:
  1. <bridge>namespaceclassName属性以及<method>name属性让我们在客户端JavaScript中可以通过Dflying.YahooWeatherService.GetWeather()这样的方法签名来访问这个Mashup。
  2. <proxy>serviceUrl属性指定了Yahoo! Weather Service的URL。
  3. GetWeather方法中定义了上面列出来的pu两个参数,其中u参数我们指定了它的默认值为c(代表摄氏度),p参数将由调用者负责传过来。

写到这一步其实也够了,客户端将收到上面浏览器中看到的那一段XML String,并且可以在客户端进行处理并显示。但客户端对XML的处理并不是那么容易,也不是那么高效,同时通过网络传输太多不必要的信息也是一种浪费。所以这里我们利用asbx中内建的Transformer对这段XML处理一下,提取出我们感兴趣的内容并以JSON的形式发给客户端。在<method>段中加入下面一段:

None.gif < transforms >
None.gif  
< transform  type ="Microsoft.Web.Services.XPathBridgeTransformer" >
None.gif    
< data >
None.gif      
< attribute  name ="selector"  value ="channel"   />
None.gif      
< dictionary  name ="namespaceMapping" >
None.gif        
< item  name ="yweather"  value ="http://xml.weather.yahoo.com/ns/rss/1.0"   />
None.gif      
</ dictionary >
None.gif      
< dictionary  name ="selectedNodes" >
None.gif        
< item  name ="Title"  value ="title"   />
None.gif        
< item  name ="Description"  value ="item/description"   />
None.gif        
< item  name ="CurrentCondition"  value ="item/yweather:condition/@text"   />
None.gif      
</ dictionary >
None.gif    
</ data >
None.gif  
</ transform >
None.gif
</ transforms >

其中 <transforms> 声明表示这个Mashup 方法的返回值将会被一些transformer 改变一下,里面声明了一个类型为 Microsoft.Web.Services.XPathBridgeTransformer 的transformer ,表示将用 XPath 表达式来转换。在这个XPathBridgeTransformer 中要声明如下部分:
  1. nameselector的一个attribute段,其中指定的value属性为一个XPath表达式,将选取整个XPathBridgeTransformer将用到的数据段。
  2. namenamespaceMapping的一个dictionary段,其中指定了这个XML文件中的namespace映射。如果在下面的选择节点过程中我们用到了某个namespace,那么这里就必须有它的声明。这里我们在其中添加一个对yweather的映射,因为下面要用到。
  3. nameselectedNodes的一个dictionary段,其中每一个itemvalue属性是一个XPath String,用来从XML中选择出相应的值,name属性用来指定相应的在JavaScript中的属性名称。这里作为示例,我只取得其中三段内容,您可以看到,其中CurrentCondition的XPath中用到了上面指定的namespaceMapping。

关于XPath的知识,我就不多讲了,感兴趣或是不太熟悉的朋友可以自行Google,网上资源很多。关于其他类型的Transformer,我也不是很熟悉,今后如果遇到了我再讲讲。完成后的YahooWeatherBridge.asbx文件如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< bridge  namespace ="Dflying"  className ="YahooWeatherService" >
None.gif
None.gif  
< proxy  type ="Microsoft.Web.Services.BridgeRestProxy"  
None.gif         serviceUrl
="http://xml.weather.yahoo.com/forecastrss"   />
None.gif
None.gif  
< method  name ="GetWeather" >
None.gif    
< input >
None.gif      
< parameter  name ="p"   />
None.gif      
< parameter  name ="u"  value ="c"   />
None.gif    
</ input >
None.gif    
< transforms >
None.gif      
< transform  type ="Microsoft.Web.Services.XPathBridgeTransformer" >
None.gif        
< data >
None.gif          
< attribute  name ="selector"  value ="channel"   />
None.gif          
< dictionary  name ="namespaceMapping" >
None.gif            
< item  name ="yweather"  value ="http://xml.weather.yahoo.com/ns/rss/1.0"   />
None.gif          
</ dictionary >
None.gif          
< dictionary  name ="selectedNodes" >
None.gif            
< item  name ="Title"  value ="title"   />
None.gif            
< item  name ="Description"  value ="item/description"   />
None.gif            
< item  name ="CurrentCondition"  value ="item/yweather:condition/@text"   />
None.gif          
</ dictionary >
None.gif        
</ data >
None.gif      
</ transform >
None.gif    
</ transforms >
None.gif  
</ method >
None.gif
</ bridge >

现在创建一个ASP.NET Page 测试一下,首先依然是重复了一千遍的ScriptManager ,还有对Bridge 的引用:
None.gif < atlas:ScriptManager  ID ="sm"  runat ="server" >
None.gif    
< Services >
None.gif        
< atlas:ServiceReference  Path ="YahooWeatherBridge.asbx"   />
None.gif    
</ Services >
None.gif
</ atlas:ScriptManager >

然后一个HTML Select 元素,里面列入了几个城市以及相应的城市代码:
None.gif <!--  place selector  -->
None.gif
< select  id ="place" >
None.gif    
< option  selected ="selected"  value ="CHXX0116" > Shanghai, CH </ option >
None.gif    
< option  value ="USCA0746" > Mountain View, CA </ option >
None.gif    
< option  value ="CHXX0008" > Beijing, CH </ option >
None.gif
</ select >

一个HTML Button ,用来触发对Service 的调用:
None.gif <!--  invoke the service  -->
None.gif
< input  id ="getWeather"  type ="button"  value ="Get Weather"  onclick ="return getWeather_onclick()"   />

一段HTML 用来显示结果:
None.gif <!--  display result  -->
None.gif
< div  id ="result"  style ="display: none;" >
None.gif    
< div  style ="background-color: Gray; font-weight: bold;" > Title </ div >
None.gif    
< div  id ="title" ></ div >
None.gif    
< div  style ="background-color: Gray; font-weight: bold;" > Description </ div >
None.gif    
< div  id ="description" ></ div >
None.gif
</ div >

然后是JavaScript ,可以看到通过Dflying.YahooWeatherService.GetWeather() 调用了Mashup ,并在方法返回后把经过transform 的值输出到了页面上:
ExpandedBlockStart.gif ContractedBlock.gif function  getWeather_onclick()  dot.gif {
InBlock.gif    
// new atlas 'Select' control
InBlock.gif
    var place = new Sys.UI.Select($('place'));
InBlock.gif    
InBlock.gif    
// invoke the bridge method
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Dflying.YahooWeatherService.GetWeather(dot.gif{'p': place.get_selectedValue()}, onGetComplete);
ExpandedBlockEnd.gif}

ExpandedBlockStart.gifContractedBlock.gif
function  onGetComplete(result)  dot.gif {
InBlock.gif    $('result').style.display 
= "block";
InBlock.gif    $('title').innerHTML 
= result[0].Title;
InBlock.gif    $('description').innerHTML 
= result[0].Description;
ExpandedBlockEnd.gif}

最后浏览器中看一下结果,上海天气:
bridge2-1.jpg

Mountain View天气:
bridge2-2.JPG

该实例程序的源代码可以在此下载:http://files.cnblogs.com/dflying/YahooWeatherBridge.zip

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值