随笔-312  评论-12034  文章-2  trackbacks-256
作者: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!提供的天气ServiceURLhttp://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

Yahoo Weather Service XML Result

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

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

<?xml version="1.0" encoding="utf-8" ?>
<bridge namespace="Dflying" className="YahooWeatherService">

  
<proxy type="Microsoft.Web.Services.BridgeRestProxy" 
         serviceUrl
="http://xml.weather.yahoo.com/forecastrss" />

  
<method name="GetWeather">
    
<input>
      
<parameter name="p" />
      
<parameter name="u" value="c" />
    
</input>
  
</method>
</bridge>

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

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

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

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

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

<?xml version="1.0" encoding="utf-8" ?>
<bridge namespace="Dflying" className="YahooWeatherService">

  
<proxy type="Microsoft.Web.Services.BridgeRestProxy" 
         serviceUrl
="http://xml.weather.yahoo.com/forecastrss" />

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

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

然后一个HTML Select元素,里面列入了几个城市以及相应的城市代码:

<!-- place selector -->
<select id="place">
    
<option selected="selected" value="CHXX0116">Shanghai, CH</option>
    
<option value="USCA0746">Mountain View, CA</option>
    
<option value="CHXX0008">Beijing, CH</option>
</select>

一个HTML Button,用来触发对Service的调用:

<!-- invoke the service -->
<input id="getWeather" type="button" value="Get Weather" onclick="return getWeather_onclick()" />

一段HTML用来显示结果:

<!-- display result -->
<div id="result" style="display: none;">
    
<div style="background-color: Gray; font-weight: bold;">Title</div>
    
<div id="title"></div>
    
<div style="background-color: Gray; font-weight: bold;">Description</div>
    
<div id="description"></div>
</div>

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

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

最后浏览器中看一下结果,上海天气:

Mountain View天气:

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

posted on 2006-05-26 11:58 Dflying Chen 阅读(5074) 评论(34)  编辑 收藏 网摘 所属分类: ASP.NET AJAX (Atlas)

评论:
#1楼  2006-05-26 12:52 | 阿不      
看完了。
  回复  引用  查看    
#2楼 [楼主] 2006-05-26 13:16 | Dflying Chen      
@阿不
好玩么?

  回复  引用  查看    
#3楼  2006-05-26 13:35 | 阿不      
呵呵,挺好玩的。要学得太多了,特别是最近的Script#。能否还把Mashup理解为Web Service代理。最近一直忙,没时间经常上来了。
  回复  引用  查看    
#4楼  2006-05-26 13:36 | 阿不      
你的排名上升太快了吧?Cool
  回复  引用  查看    
#5楼 [楼主] 2006-05-26 14:01 | Dflying Chen      
@阿不
可以的,Mashup就是典型的Proxy设计模式。

  回复  引用  查看    
#6楼 [楼主] 2006-05-26 14:01 | Dflying Chen      
@阿不
谢谢

  回复  引用  查看    
#7楼  2006-05-26 14:06 | stonezhu      
你好强啊,佩服
  回复  引用  查看    
#8楼  2006-05-26 14:07 | stonezhu      
一直在观注你的文章:)
  回复  引用  查看    
#9楼  2006-05-26 14:28 | 梁广永      
学习,
  回复  引用  查看    
#10楼 [楼主] 2006-05-26 14:31 | Dflying Chen      
@stonezhu
@梁广永
谢谢,共同提高!

  回复  引用  查看    
#11楼  2006-05-26 16:33 | leafyoung [未注册用户]
请问,下面的代码执行后报错说MessageService没有初始化,咋办呢?

<atlas:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server">
<Services>
<atlas:ServiceReference Path="MessageService.asmx" />
</Services>
</atlas:ScriptManager>
...
<script type="text/javascript">
function onMyLoad()
{
MessageService.HelloWorld(onSendComplete);
}

</script>
...
<body onload="onMyLoad();">

  回复  引用    
#12楼 [楼主] 2006-05-26 16:40 | Dflying Chen      
@leafyoung
<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<components>
<application id="application" load="onMyLoad" />
</components>
</page>
</script >

.......

<script type="text/javascript">
function onMyLoad()
{
MessageService.HelloWorld(onSendComplete);
}

</script>

  回复  引用  查看    
#13楼  2006-05-26 23:04 | Quan [未注册用户]
预览时会出现错误。
分析器错误信息: 无法识别的属性“type”。

源错误:


行 13: -->
行 14: <configSections>
行 15: <sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup">
行 16: <section name="converters" type="Microsoft.Web.Configuration.ConvertersSection" requirePermission="false"/>
行 17: <section name="webServices" type="Microsoft.Web.Configuration.WebServicesSection"/>



怎么回事啊!

  回复  引用    
#14楼  2006-05-26 23:23 | 维生素C.NET      
这mashup可以atlas向web 2.0靠近甚至引领的宝贝东西。
  回复  引用  查看    
#15楼 [楼主] 2006-05-27 07:52 | Dflying Chen      
@Quan
错误在多少行阿?

  回复  引用  查看    
#16楼 [楼主] 2006-05-27 07:54 | Dflying Chen      
@维生素C.NET
Mashup很有用的

  回复  引用  查看    
#17楼  2006-05-27 13:26 | leafyoung [未注册用户]
@Dflying Chen:
还有个问题请教一下,我通过css给web page加了背景图片后,发现使用UpdatePanel的效果不是很理想,虽然页面确实只有某个部分刷新了,但是整个背景好像全都重新绘制了,导致出现严重闪烁,而设置背景色就不会有问题,这个问题应该如何解决呢?

B.T.W. 谢谢昨天及时回答我的问题,呵呵@_@~~~

  回复  引用    
#18楼 [楼主] 2006-05-27 15:14 | Dflying Chen      
@leafyoung
UpdatePanel的效率确实不好,特别是里面包含着太多的内容。
现实就是这样,鱼与熊掌不可兼得,UpdatePanel的开发效率很高,执行效率自然会受到一些影响。
但背景图片的问题,估计与UpdatePanel关系不大,您在其他浏览器中看看如何呢?

  回复  引用  查看    
#19楼  2006-10-09 17:29 | changhai-xuri [未注册用户]
我倒想起一个问题,先在一个测试解决方案中测试,通不过。
只好另建一个单独测试,倒是通过了,多谢!
我想起了一个问题,一个asbx文件是不是只能建一个bridge ,也就是说只能引用一个service,在上一篇中有说到serviceUrl=""我看了好像地址后面包含了方法名称的, <method name="GetWeather">这个name是引用名称是吧,那如果服务中有多个方法,如何能引用到不同的方法。

如果有多个方法呢,有不同的service呢,如何Mashup

  回复  引用    
#20楼  2006-10-10 10:12 | hnshouping [未注册用户]
为什么例子中老说result[0].Title为空,或不是对象呢.
  回复  引用    
#21楼  2006-10-22 14:10 | orivan [未注册用户]
知道哥们儿你正因为 asp.net ajax beta 发布郁闷呢,不过新版的DLL文件原来的Bridge的东西都没有了,对于新版来说Cross Site/Domain Web Service应该采取一种什么样的解决方案呢?
  回复  引用    
#22楼 [楼主] 2006-10-24 08:57 | Dflying Chen      
@changhai-xuri
可以有不同的Bridge的,只要在asbx这个XML文件中相应地添加一段声明即可

  回复  引用  查看    
#23楼 [楼主] 2006-10-24 08:57 | Dflying Chen      
@hnshouping
又没有看过HTTP嗅探器的结果呢?有没有数据返回呢?

  回复  引用  查看    
#24楼 [楼主] 2006-10-24 08:58 | Dflying Chen      
@orivan
不会吧?怎么可能的……我来看看……

  回复  引用  查看    
#25楼  2006-10-24 12:54 | orivan [未注册用户]
呵呵,看得怎么样?反正原来那个方法我不会用了,我现在在客户端直接用了 Sys.Net.WebRequest 的方法获取自己站点上的一个 .aspx 页,然后这个页的 load 方法里边通过 XMLHTTP 对 Web Service 进行内容获取和解析了,笨了点,不过能用。。。
  回复  引用    
#26楼  2006-10-24 12:56 | orivan [未注册用户]
呵呵,正好省了服务器配置 .asbx 这个映射。
  回复  引用    
#27楼 [楼主] 2006-10-24 14:08 | Dflying Chen      
@orivan
这样也好……

  回复  引用  查看    
#28楼  2006-10-24 16:20 | orivan [未注册用户]
反正我也只能做到这样了,更高级的方法就等你研究了,呵呵……例子里边好像有 Mash-up 的方案,不过现在也没有配环境,就没有细看。
  回复  引用    
#29楼 [楼主] 2006-10-24 19:08 | Dflying Chen      
@orivan
恩,过一段时间一定研究。

  回复  引用  查看    
#30楼  2007-01-12 15:58 | noir [未注册用户]
Dflying.YahooWeatherService.GetWeather()
这个函数返回什么呢?如果我用C#.net写,怎么实现这个函数呢?

  回复  引用    
#31楼 [楼主] 2007-01-29 11:36 | Dflying Chen      
@noir
返回一段XML,这个就是C#写的

  回复  引用  查看    
#32楼  2008-04-02 18:59 | 螞蟻漫步      
引用,谢谢!
  回复  引用  查看    

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接: