Google Weather API with RestSharp

Guest post by DK!

The Google Weather API is a grand service for developers to get weather data for any location with ease.

RestSharp is a open source .NET REST Client…

Been doing some work getting weather information from Google Weather and I thought I might take the time to explain how I used Restsharp with this API. I started with the xml from the API itself.

http://www.google.com/ig/api?weather=Brisbane+au

<xml_api_reply version="1">
    <weather>
        <forecast_information>
            <city data="Brisbane, QLD"/>
            <postal_code data="Brisbane au"/>
            <latitude_e6 data=""/>
            <longitude_e6 data=""/>
            <forecast_date data="2010-04-14"/>
            <current_date_time data="2010-04-14 14:00:00 +0000"/>
            <unit_system data="US"/>
        </forecast_information>
        <current_conditions>
            <condition data="Partly Cloudy"/>
            <temp_f data="72"/>
            <temp_c data="22"/>
            <humidity data="Humidity: 64%"/>
            <icon data="/ig/images/weather/partly_cloudy.gif"/>
            <wind_condition data="Wind: SW at 14 mph"/>
        </current_conditions>
        <forecast_conditions>
            <day_of_week data="Wed"/>
            <low data="64"/>
            <high data="78"/>
            <icon data="/ig/images/weather/chance_of_rain.gif"/>
            <condition data="Chance of Rain"/>
        </forecast_conditions>
	  ...
    </weather>
</xml_api_reply>

Notice the weather element contains multiple forecast_conditions elements without a single container element as well as the other forecast_information and current_conditions elements. At first this was a problem, I spoke to John Sheehan (the creator of RestSharp) about this and he told me it was currently unsupported with RestSharp. So I took a dive into the RestSharp source (mainly the XmlDeserialiser) to try and find a solution to this problem and I came across the support for Derived Lists, therein lies a solution…

public class xml_api_reply
{
    public string version { get; set; }
    public Weather weather { get; set; }
}
public class Weather : List<Forecast_Conditions>
{
    public Forecast_Information Forecast_Information { get; set; }
    public Current_Conditions Current_Conditions { get; set; }
}
public class DataElement
{
    public string Data { get; set; }
}
public class Forecast_Information
{
    public DataElement City { get; set; }
    public DataElement Postal_Code { get; set; }
    public DataElement Forecast_Date { get; set; }
    public DataElement Unit_System { get; set; }
}
public class Current_Conditions
{
    public DataElement Condition { get; set; }
    public DataElement Temp_c { get; set; }
    public DataElement Humidity { get; set; }
    public DataElement Icon { get; set; }
    public DataElement Wind_condition { get; set; }
}
public class Forecast_Conditions
{
    public DataElement Day_Of_Week { get; set; }
    public DataElement Condition { get; set; }
    public DataElement Low { get; set; }
    public DataElement High { get; set; }
    public DataElement Icon { get; set; }
}

These classes are then used by RestSharp to Deserialise the response. xml_api_reply is the root element and under it is weather. The weather class inherits from a List<forecast_conditions> because it can contain multiple elements as well as other properties. The DataElement class was created because of the way the xml has its data ie. <city data=”Brisbane, QLD”/>  instead of <city>Brisbane, QLD</city>.

Now that we have setup the Response classes we can use get to the real code…

var client = new RestClient("http://www.google.com/ig/api");
var request = new RestRequest(Method.GET);
request.AddParameter("weather", "Brisbane");

var response = client.Execute<Models.xml_api_reply>(request);

Pretty easy, and the response is a RestResponse<T> where T is my xml_api_reply class, this object then gives us access to anything we could need from the response including the content itself (response.Content) and the deserialised class (response.Data).

And to find the current temperature:

response.Data.weather.Current_Conditions.Temp_c.Data

Now you know how to use RestSharp the world of Restful services is yours for the taking!

Update: Updated the reponse class to Pascal Case.

8 Responses

  1. Great post guys! Very cool to see RestSharp work in ways I didn’t anticipate. I actually didn’t know that derived lists would work like that. I should make sure to create a deserializer unit test to make sure it continues to do so.

    On other thing. If you prefer, you can name your classes and properties using Pascal Casing and they will continue to work. You can see how the name matching works here: http://wiki.github.com/johnsheehan/RestSharp/deserialization

  2. Hey john – We are actually using rest sharp for a heap of music related APIs in our upcoming site http://promote.fm. Its been a massive timesaver. I will try show a few more examples from that project when I have some time.

  3. dk says:

    Hi John, Been following your work on RestSharp for a while now and its been a great tool.
    As for the Pascal Casing of classes for some reason i think the name for the Listed object has to match the name of the element (need to do some testing on this)
    I have added a Deserialiser test to my fork of RestSharp using the google weather XML if you wanted to use that.
    I also found out that this derived list method doesnt work if the main type is a generic as i tried using Weather : List but it just found it as a regualr list in the deserialiser and looked for the containing element.

  4. Luke, can’t wait to see more examples!

    dk, I thought I had fixed that list item naming bug, but I will doublecheck. Can you create a GitHub issue with all your details so I don’t forget?

  5. Pingback: Rest Web Services In Windows Phone 7 | lukencode

  6. Stefan Stranger says:

    Hi Luke,

    Trying to follow your example but hitting the next error:
    Error 1 ‘RestSharp.RestClient’ does not contain a definition for ‘Execute’ and no extension method ‘Execute’ accepting a first argument of type ‘RestSharp.RestClient’ could be found (are you missing a using directive or an assembly reference?)

    Any ideas?

    Regards,
    Stefan

  7. Adhi Ravishankar says:

    Could you give us the complete source code in a download?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>