Author: Dflying Chen ( http://dflying.cnblogs.com/ )
In the previous article (Calling Web Service in ASP.NET Atlas - Creating Mashup to Call Remote Web Service (Basic Knowledge and Simple Example)), I introduced some basic knowledge of Mashup for remote Web Service in Atlas. And gave a most basic example that is not useful at all. Returning to this topic today, I will give a more complex, but somewhat useful example - Yahoo! Weather.
Enough nonsense, let us first familiarize ourselves with the Yahoo! Weather service: Yahoo! provides a weather forecast service on its website ( http://weather.yahoo.com/ ), and it also provides a Web Service interface ( http ://developer.yahoo.com/weather/ )
From the above two web pages, we can know that the URL of the weather service provided by Yahoo! is http://xml.weather.yahoo.com/forecastrss . The service also has two parameters:
p: the location code where the weather is to be queried ( You can check this code in different places at http://weather.yahoo.com/ ).
u: The unit of the temperature in the returned result, f represents Fahrenheit, and c represents Celsius.
It seems that this Yahoo! Weather service is quite simple. Let us test whether it works well. First go to http://weather.yahoo.com/ and find out that the location code of Shanghai is CHXX0116. Then enter http://xml.weather.yahoo.com/forecastrss?p=CHXX0116&u=c in the browser. Well, the following not very complicated XML is returned:
Yahoo Weather Service XML Result
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<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 #">
<channel>
<title>Yahoo! Weather - Shanghai, CH</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Shanghai__CH/*http://xml.weather.yahoo.com/forecast/CHXX0116_c.html</link>
<description>Yahoo! Weather for Shanghai, CH</description>
<language>en-us</language>
<lastBuildDate>Thu, 25 May 2006 11:00 am CST</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Shanghai" region="" country="CH" />
<yweather:units temperature="C" distance="km" pressure="mb" speed="kph" />
<yweather:wind chill="21" direction="260" speed="14" />
<yweather:atmosphere humidity="78" visibility="299" pressure="0" rising="0" />
<yweather:astronomy sunrise="4:52 am" sunset="6:50 pm" />
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com/</link>
<url>/u/info_img/2009-06/30/main_142b.gif</url>
</image>
<item>
<title>Conditions for Shanghai, CH at 11:00 am CST</title>
<geo:lat>31.17</geo:lat>
<geo:long>121.43</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Shanghai__CH/*http://xml.weather.yahoo.com/forecast/CHXX0116_c.html</link>
<pubDate>Thu, 25 May 2006 11:00 am CST</pubDate>
<yweather:condition text="Fog" code="20" temp="21" date="Thu, 25 May 2006 11:00 am CST" />
<description>
<![CDATA[
<img src=" <b>Current Conditions:</b><br />
Fog, 21 C<BR /><BR />
<b>Forecast:</b><BR />
Thu - Scattered Thunderstorms. High: 25 Low: 20<br />
Fri - AM Showers. High: 26 Low: 18<br />
<br />
<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/>
(provided by The Weather Channel)<br/>
]]>
</description>
<yweather:forecast day="Thu" date="25 May 2006" low="20" high="25" text="Scattered Thunderstorms" code="38" />
<yweather:forecast day="Fri" date="26 May 2006" low="18" high="26" text="AM Showers" code="39" />
<guid isPermaLink="false">CHXX0116_2006_05_25_11_0_CST</guid>
</item>
</channel>
</rss>
<!-- p1.weather.scd.yahoo.com uncompressed/chunked Thu May 25 20:49:07 PDT 2006 -->
We can see that the information it provides is very comprehensive (even the sunrise and sunset times...) , let us write the asbx Bridge page to Mashup this Service.
First, referring to the asbx statement in the article Calling Web Service in ASP.NET Atlas - Creating Mashup to Call Remote Web Service (Basic Knowledge and Simple Example), we can write the following paragraph:
<?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>
in:
The namespace and className attributes of <bridge> and the name attribute of <method> allow us to access this Mashup in client JavaScript through method signatures such as Dflying.YahooWeatherService.GetWeather().
The serviceUrl attribute of <proxy> specifies the URL of the Yahoo! Weather Service.
The GetWeather method defines the two parameters p and u listed above. We have specified the default value of the u parameter as c (representing degrees Celsius), and the p parameter will be passed by the caller.
This step is actually enough. The client will receive the XML String seen in the browser above, and it can be processed and displayed on the client. But the client's processing of XML is not that easy or efficient, and transmitting too much unnecessary information over the network is also a waste. So here we use the built-in Transformer in asbx to process this XML, extract the content we are interested in and send it to the client in the form of JSON. Add the following paragraph to the <method> section:
<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>
The <transforms> statement indicates that the return value of this Mashup method will be changed by some transformers. It declares a transformer of type Microsoft.Web.Services.XPathBridgeTransformer, which means that XPath expressions will be used for conversion. The following parts should be declared in this XPathBridgeTransformer:
name is an attribute segment of the selector, and the specified value attribute is an XPath expression, which will select the data segment that will be used by the entire XPathBridgeTransformer.
name is a dictionary segment of namespaceMapping, which specifies the namespace mapping in this XML file. If we use a certain namespace in the following node selection process, then its declaration must be here. Here we add a mapping to yweather, because it will be used below.
name is a dictionary segment of selectedNodes, where the value attribute of each item is an XPath String, used to select the corresponding value from XML, and the name attribute is used to specify the corresponding attribute name in JavaScript. As an example here, I only obtained three pieces of content. You can see that the namespaceMapping specified above is used in the XPath of CurrentCondition.
I won’t go into details about XPath. Friends who are interested or not familiar with it can Google it by themselves. There are many online resources. I am not very familiar with other types of Transformers. I will talk about them if I encounter them in the future. The completed YahooWeatherBridge.asbx file is as follows:
<?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>
Now create an ASP.NET Page to test. First, there is still the ScriptManager repeated a thousand times, and a reference to Bridge: <atlas:ScriptManager ID="sm" runat="server">
<Services>
<atlas:ServiceReference Path="YahooWeatherBridge.asbx" />
</Services>
</atlas:ScriptManager>
Then there is an HTML Select element, which lists several cities and corresponding city codes:
<!-- 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>
An HTML Button used to trigger the call to the Service:
<!-- invoke the service -->
<input id="getWeather" type="button" value="Get Weather" onclick="return getWeather_onclick()" />
A piece of HTML is used to display the result:
<!-- 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>
Then comes JavaScript. You can see that Mashup is called through Dflying.YahooWeatherService.GetWeather(), and the transformed value is output to the page after the method returns: 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;
}