C# String Extension Methods

Ah extension methods… where would we be without them? Writing slightly more code to perform common functions that’s where! I am fairly sure everyone has their own set of string extensions so I though I’d share what I currently have then you guys can shoot it down and direct me to / yell at me something more useful. Everybody wins!

I am also experimenting with using Github’s Gist for my code samples (with help from a handy wordpress plugin). The idea is this makes it easier for me to update and you to clone, steal, comment, share etc. Let me know if it works.

Google and Yahoo Add to Calendar Html Helpers for Asp.net MVC

I’ve been working on implementing some iCal functionality for the my gig guide website – Gigpig so users could easily add concert dates to their calendars. This works fine and dandy if you have some desktop program to handle iCal files. I have however been informed that the cool kids roll with Google Calendar (and some strange people with Yahoo?!). I dug around a bit and found you can easily prompt users to add events to these calendars using a link to the calendar with the event details in the query string.

If you want to play around with these parameters I recommend using google’s tools to create a button for google calendar and following the guide on this site for yahoo.

I’ve gone ahead and wrapped them up into some Html helpers for Asp.Net MVC. I didn’t go overboard with the options here so if you will probably want to tweak the code a bit.

Calling the helpers is a little wieldy but gets the job done (yahoo is more of the same).

<%= Html.GoogleCalendar("add to google calendar", "a test event!", DateTime.Now, null, "its a test", "testington", "websitename", "www.website.com") %>

Here are some rendered links I prepared earlier:

Google Calendar Event

Yahoo Calendar Event

Rest Web Services In Windows Phone 7

I’ve been messing around with some Window Phone 7 development lately and thought I would share how I have been calling web services with RestSharp (I’ve written a little about RestSharp previously using the google weather api).

restsharp For those who don’t know RestSharp is a REST client for .NET which has recently added silverlight and Windows Phone 7 support. RestSharp has some really great features to simplify calling web services including:

  • Automatic XML and JSON deserialization
  • Fuzzy name matching (‘product_id’ in XML/JSON will match property named ‘ProductId’)
  • Automatic detection of type of content returned
  • GET, POST, PUT, HEAD, OPTIONS, DELETE supported

Windows Phone 7 basically enforces (with good reason) async web requests – luckily RestSharp has our back on that front. I’m going to use some example code from the Google Reader app I’ve been playing around with – GREAD. Here is a simple example of asynchronously calling a web service using RestSharp to authenticate with with google accounts:

var client = new RestClient("https://www.google.com");

var request = new RestRequest("accounts/ClientLogin", Method.POST);
request.AddParameter("service", "reader", ParameterType.GetOrPost);
request.AddParameter("accountType", "GOOGLE", ParameterType.GetOrPost);
request.AddParameter("source", _source, ParameterType.GetOrPost);
request.AddParameter("Email", _username, ParameterType.GetOrPost);
request.AddParameter("Passwd", _password, ParameterType.GetOrPost);

client.ExecuteAsync(request, (response) =>
{
    var auth = ParseAuthToken(response.Content);
});

RestSharp will automatically build the request with the parameters it is given. These can be get/post, cookies or http headers. The ExecuteAsync method takes the request to make and an action to execute when finished.

I come from a web development background living the good life making synchronous requests. Developing in Silverlight requires a bit of an adjustment with a big focus on event driven asynchronous programming. The pattern I am using I’ve tried to avoid all the plumbing involved in hooking up and firing off event handlers. Here is the basic pattern I use for api calls, in this instance I am grabbing all the feed items for the given label:

public void GetLabelFeed(string label, Action<Model.Feed> success, Action<string> failure)
{
    string resource = "reader/api/0/stream/contents/user/-/label/" + label;

    var request = GetBaseRequest();
    request.Resource = resource;
    request.Method = Method.GET;
    request.AddParameter("n", 20); //number to return

    _client.ExecuteAsync<Model.Feed>(request, (response) =>
    {
        if (response.ResponseStatus == ResponseStatus.Error)
        {
            failure(response.ErrorMessage);
        }
        else
        {
            success(response.Data);
        }
    });
}

I pass two callbacks to the method, one for success and one for failure. In this example I am using RestSharp’s auto deserialzation into the class Model.Feed by calling ExecuteAsync<Model.Feed>(). Depending on the status of the request either failure or success action is called.

To use these methods in my wp7 application I use inline delegates to handle the events. One thing to be aware of is the code on these callbacks will run in the background thread and you wont see anything change on the UI. To fix this make sure the data binding code is executed in the UI thread using the dispatcher. I use a DispatcherHelper class borrowed from the MVVM Light Toolkit.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
	api.GetLabelFeed(
    	feedId,
    	(items) => DispatcherHelper.SafeDispatch(() =>
    	{
        	this.DataContext = items;
        	progressBar.Visibility = System.Windows.Visibility.Collapsed;
    	}),
    	(error) => DispatcherHelper.SafeDispatch(() =>
    	{
        	MessageBox.Show(error);
        	progressBar.Visibility = System.Windows.Visibility.Collapsed;
    	}));

    	base.OnNavigatedTo(e);
}

I found this structure has kept my code reasonable clean and has handled all cases in the simple web requests I have made but since I’m new to Silverlight I’m sure it could be better.

Windows Phone 7 Google Reader App (GREAD) Work In Progress

I’ve spent the last couple of days playing around with some Windows Phone 7 development. I decided to create a simple Google reader client as a practice app that later on down the track might at least be useful to me. Considering I have no background in Silverlight (mainly just web applications) I think I’ve managed to come quite a long way in a short amount of time.

 

The app current pulls in the given users unread counts and labels on the home screen with the labels located a swoosh to the right. From there you can jump straight to view a story or drill down into one of your labels.

Before I go too much further I would like to try get some feedback/ideas on what people want from a Google reader client (if anything).

The design is obviously a little dodgy at the moment my main plan here is to try utilized the wp7 concept of horizontal space. I am waiting for the official panorama/pivot controls and will look to implement those.

Features wise at the moment all the client does is query the Google reader api for feeds an stories. I am going to implement the core reader functionality – read and unread, starring and notes as well as some type of social sharing.  I’d like to know how important offline reading / caching is to people so I can decide how much effort I need to put into that side of the application.

If you have any ideas let me know in the comments or on twitter – @lukencode.

Getting Started With MongoDB and NoRM

I just realised – I hate writing SQL. I hate it, I hate it, I hate it. I have also recently noticed a growing trend in SQL alternatives or “nosql” with open source C# drivers. Today I put one and one together and decided to try out one of these – MongoDB using the C# driver NoRM. Why this idea didn’t occur to me earlier I will never know.

What is MongoDB?

logo-mongodb MongoDB is one of a growing number of nosql databases. In short these databases are non relational and schema free. I won’t attempt to give a full rundown of the pros and cons of nosql but the stated benefits are generally saleability, performance and simplicity.

MongoDB is a document orientated database storing data on disk as binary json. Some key features include indexing, rich queries, map reduce and horizontal scalability.

The Mongo website sums it all up much better than I do so you should probably just go there:

MongoDB bridges the gap between key-value stores (which are fast and highly scalable) and traditional RDBMS systems (which provide rich queries and deep functionality).

MongoDB (from "humongous") is a scalable, high-performance, open source, document-oriented database.

For installation instructions for Mongo I recommend taking a look at the Windows Quickstart guide.

What (or who) is NoRM?

normLogo NoRM is an open source .Net library for connecting to MongoDB. Its main drawcards for me are:

  • NoRM is strongly typed. It uses plain .net classes when querying and updating the database.
  • Uses linq for queries
  • Simple and convention based. NoRM makes it really simple to get persistence up and running as I will soon demonstrate.

To get NoRM head over to http://github.com/atheken/NoRM.

Using NoRM in C#

I’m going to be using NoRM with a pretty standard session pattern. My MongoSession will implement the following ISession interface which uses linq expressions for queries.

public interface ISession : IDisposable
{
    void CommitChanges();
    void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
    void Delete<T>(T item) where T : class, new();
    void DeleteAll<T>() where T : class, new();
    T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
    System.Linq.IQueryable<T> All<T>() where T : class, new();
    void Add<T>(T item) where T : class, new();
    void Add<T>(IEnumerable<T> items) where T : class, new();
    void Update<T>(T item) where T : class, new();
}

 

The MongoSession class is based off the one found in the mvcstarter project and uses NoRM to implement ISession. The constructor for this class sets up the Mongo connection looking for a web.config connection string entry named “db”. An example connection string is given after the code.

public class MongoSession : ISession
{
    private Mongo _provider;
    public MongoDatabase DB { get { return this._provider.Database; } }

    public MongoSession()
    {
        //this looks for a connection string in your Web.config
        _provider = Mongo.Create("db");
    }

    public void CommitChanges()
    {
        //mongo isn't transactional in this way
    }

    public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class, new()
    {
        var items = All<T>().Where(expression);
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void Delete<T>(T item) where T : class, new()
    {
        DB.GetCollection<T>().Delete(item);
    }

    public void DeleteAll<T>() where T : class, new()
    {
        DB.DropCollection(typeof(T).Name);
    }

    public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class, new()
    {
        return All<T>().Where(expression).SingleOrDefault();
    }

    public IQueryable<T> All<T>() where T : class, new()
    {
        return _provider.GetCollection<T>().AsQueryable();
    }

    public void Add<T>(T item) where T : class, new()
    {
        DB.GetCollection<T>().Insert(item);
    }

    public void Add<T>(IEnumerable<T> items) where T : class, new()
    {
        foreach (T item in items)
        {
            Add(item);
        }
    }

    public void Update<T>(T item) where T : class, new()
    {
        DB.GetCollection<T>().UpdateOne(item, item);
    }

    //Helper for using map reduce in mongo
    public T MapReduce<T>(string map, string reduce)
    {
        T result = default(T);
        MapReduce mr = DB.CreateMapReduce();

        MapReduceResponse response =
            mr.Execute(new MapReduceOptions(typeof(T).Name)
            {
                Map = map,
                Reduce = reduce
            });
        IMongoCollection<MapReduceResult<T>> coll = response.GetCollection<MapReduceResult<T>>();
        MapReduceResult<T> r = coll.Find().FirstOrDefault();
        result = r.Value;

        return result;
    }

    public void Dispose()
    {
        _provider.Dispose();
    }
}

 

<connectionStrings>
  <add name="db" connectionString="mongodb://localhost/testdb?strict=true"/>
</connectionStrings>

 

One of the best things about Mongo and NoRM is that NoRM will store plain and simple .net objects. This means we can define our models completely in code. Because Mongo is schema less we can also add and remove properties without any problems.

I am going to store a simple Trip class for a scheduling application. There are a couple of things to note about this code, first is the [MongoIdentifier] Attribute. Mongo requires collections have a unique identifier. When using NoRM the options you can use are: Guid/UUID, int, or ObjectId. The property must also be named either _id or Id. NoRM will handle generating the identifier when it is required. To keep my example simple I am using an integer. For more complete guidelines check the BSON Serializer page.

public class Trip
{
    [MongoIdentifier]
    public int? Id { get; set; }
    public string Name { get; set; }

    public DateTime Start { get; set; }
    public int Duration { get; set; }

    public Trip()
    {
        Start = DateTime.Now;
    }
}

 

The code to store the Trip class is very simple. The session’s add method will automatically store the object in the database as well as assigning it an Id.

var trip = new Trip()
{
    Name = "test trip",
    Duration = 5,
    Start = DateTime.Now
};

using (var session = new MongoSession())
{
    session.Add(trip);
}

 

BAM! Here is the object I just saved viewed in the mongo shell. It has been assigned an identifier and stored in a collection called Trip. There was no need to define the structure of the object or to create a collection to store it in, this all happens automatically and is part of what makes coding with Mongo so refreshing.

shell

 

Finding the document with code is simple using the linq methods of MongoSession.

using (var session = new MongoSession())
{
    var trip = session.Single<Trip>(t => t.Name == "test trip");
}

 

This is obviously a very basic overview of programming with Mongo and NoRM and therefore I have skipped over some of the more advanced features. NoRM’s linq provider is pretty good but on complex queries you may run into some issues. NoRM also has some configuration code you can add to optimise the way your objects are stored. Overall I am finding working without the constraints of a schema and letting your code define your data storage is a great way to program.

IP to Geo Location in Asp.Net MVC

I have been working on a couple of projects recently (like the new and improved version of Gigpig which is coming soon!) which could really benefit from some automagic geolocation lookups for visitors. In the case of Gigpig I wanted to filter what gigs users could see based on where they were in the world.

The database I am using is the binary version of the Max Mind GeoLite City free location database. The database essentially maps IP address ranges to cities and countries.  The binary format, I am informed is the fastest version however there is a csv file you can download and import into your database of choice.

Max Mind provide some C# code for querying the binary database but it takes a little work to set up where as I never like doing work someone else has done for me. The library I use is the GoogleMaps.Subgurim.NET which as well as from google map functions provides code to access the GeoLite City database.

The code to call the Subgurim methods is super simple. Here I am returning the location class which is also included in the library – it has properties for longitude, latitude, country, city and a few other things. All that needs to be passed to it is the location of your database and the ip address you want to look up.

public static Location GetLocationFromIP(string ipAddress)
{
    string databasePath = HttpContext.Current.Server.MapPath("~/app_data/geocitylite.dat");
    LookupService service = new LookupService(databasePath);
    Location loc = service.getLocation(ipAddress);

    return loc;
}

One way I like to use this code in Asp.Net MVC is including some properties in a base controller class that my controllers all inherit so I can access the current location on any controller. One thing to be aware of is the lookup will return null for the ip address 127.0.0.1 so you might want to hard code it for testing.

public class ControllerBase : Controller
{
    public string CurrentUserIPAddress
    {
        get
        {
            return HttpContext.Request.UserHostAddress;
        }
    }

    public Location CurrentLocation
    {
        get
        {
            if (Request.Cookies["pref"] == null)
            {
                var loc = LocationHelper.GetLocationFromIP(CurrentUserIPAddress);

                if (loc != null)
                {
                    Response.Cookies["pref"]["city"] = loc.city;
                    Response.Cookies["pref"]["country"] = loc.countryCode;
                    Response.Cookies["pref"]["lat"] = loc.latitude.ToString();
                    Response.Cookies["pref"]["lng"] = loc.longitude.ToString();
                    Response.Cookies["pref"].Expires = DateTime.Now.AddDays(1);
                }

                return loc;
            }
            else
            {
                var loc = new Location
                {
                    city = Request.Cookies["pref"]["city"],
                    countryCode = Request.Cookies["pref"]["country"],
                    latitude = Convert.ToDouble(Request.Cookies["pref"]["lat"]),
                    longitude = Convert.ToDouble(Request.Cookies["pref"]["lng"]),
                };

                return loc;
            }
        }
    }
}

I also cache the user’s location in a cookie so I can avoid doing a database query for every request. There are a couple of ways you could implement IP address to geo location including some variations of this code – but if you just want something quick and easy this is a good starting point.

Timesaving CSS Tools for ASP.Net Developers

Are you a developer?

Are you a lazy developer?

Do you hate doing web design?

If you answered yes to that last question you have come to the right blog post. I am going to show you three simple to use libraries to make working with CSS much less painful giving you time to get back to the good stuff – pointlessly refactoring your code!

1. Blueprint CSS

First cab off the rank is the Blueprint CSS Framework. Blueprint combines a solid reset file,  good looking default typography and an easy to use grid system.

The purpose of the reset file is fairly straightforward – removing some browser inconsistencies.

The typography defaults are great as a sane starting point for padding, sizes, line height and all the other stuff designers write novels on but us developers have really no idea about. The values are also set in em so they should scale to the user’s font size appropriately.

Last but not least is Blueprint’s grid system. This I am not totally sold on but at the very least its useful for getting together a quick prototype. Essentially the system uses classes such as ‘container’, ‘span-10’ and ‘last’ to quickly and easily bust out complex layouts.

Here is a basic example with a header, content, footer and sidebars.

<div class="container">
    <div class="span-24 last">
        Header
    </div>
    <div class="span-4">
        Left sidebar
    </div>
    <div class="span-16">
        Main content
    </div>
    <div class="span-4 last">
        Right sidebar
    </div>
</div>

2. Bundler

When building a public facing website its usually a good idea to combine and minify your CSS(and javascript) files into a single file. This of course is a huge pain in the ass. It is possible to use something like the Yahoo YUI Compressor and an MSBuild task to automate this but then you run into problems for things like debugging your CSS.

Enter Bundler. Bundler essentially reduces combining and minifying of CSS and javascript into on tiny bit of code -

<%= Bundle.Css()
        .AddCss("~/css/reset.css")
        .AddCss("~/css/site.css")
        .RenderCss("~/css/combined.css") %>

Bundler combines and minifies reset.css and site.css into one file – combined.css. It also takes care of ensuring old files aren’t cached and will not combine your files if the website is running in debug mode. Using bundler you have the freedom to split your CSS up into manageable pieces without sacrificing load times.

3. LESS CSS (using Bundler)

Last on the list is LESS CSS.

In its own words – “LESS extends CSS with: variables, mixins, operations and nested rules”.

In my words LESS allows you to write CSS more like you would normally write code allowing you to keep your CSS files DRY (don’t repeat yourself… dammit I just repeated myself). It achieves this by using this variables, mixins which are kind of like functions and a few other nifty features.

For the two readers who have gotten this far and clicked through the link will notice LESS CSS is targeted at ruby and not at .Net. However our good friend from step 2 – Bundler (or dotlesscss) will automatically parse CSS files ending with .less using the LESS CSS language.

Variables behave exactly as you would expect them to and are awesome for making sure you don’t keep repeating yourself with things like colours.

@brand_color: #4D926F;

#header {
  color: @brand_color;
}

h2 {
  color: @brand_color;
}

The other feature I really love is mixins. Mixins behave in a way like functions that take parameters as input and return a set of CSS properties based off those parameters. CSS 3 rounded corners are a good example of this.

.rounded_corners (@radius: 5px) {
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
  border-radius: @radius;
}

#header {
  .rounded_corners;
}

LESS has a number of other cool features you can check out on the documentation.

Calling Web Services in Android using HttpClient

I’ve decided recently to branch out from mainly web development into the mobile app space – starting with Google’s Android (because I own a Android phone). One of the first things I wanted to do was start calling webservices, specifically Google Analytics.

Now I am pretty new to Android and Java in general but I feel I’ve come up with a nice simple way to make requests to web services and APIs (and plain html pages if you want). The class uses the org.apache.http library which is included in Android.

This is the code for the class.

public class RestClient {

    private ArrayList <NameValuePair> params;
    private ArrayList <NameValuePair> headers;

    private String url;

    private int responseCode;
    private String message;

    private String response;

    public String getResponse() {
        return response;
    }

    public String getErrorMessage() {
        return message;
    }

    public int getResponseCode() {
        return responseCode;
    }

    public RestClient(String url)
    {
        this.url = url;
        params = new ArrayList<NameValuePair>();
        headers = new ArrayList<NameValuePair>();
    }

    public void AddParam(String name, String value)
    {
        params.add(new BasicNameValuePair(name, value));
    }

    public void AddHeader(String name, String value)
    {
        headers.add(new BasicNameValuePair(name, value));
    }

    public void Execute(RequestMethod method) throws Exception
    {
        switch(method) {
            case GET:
            {
                //add parameters
                String combinedParams = "";
                if(!params.isEmpty()){
                    combinedParams += "?";
                    for(NameValuePair p : params)
                    {
                        String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),”UTF-8″);
                        if(combinedParams.length() > 1)
                        {
                            combinedParams  +=  "&" + paramString;
                        }
                        else
                        {
                            combinedParams += paramString;
                        }
                    }
                }

                HttpGet request = new HttpGet(url + combinedParams);

                //add headers
                for(NameValuePair h : headers)
                {
                    request.addHeader(h.getName(), h.getValue());
                }

                executeRequest(request, url);
                break;
            }
            case POST:
            {
                HttpPost request = new HttpPost(url);

                //add headers
                for(NameValuePair h : headers)
                {
                    request.addHeader(h.getName(), h.getValue());
                }

                if(!params.isEmpty()){
                    request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                }

                executeRequest(request, url);
                break;
            }
        }
    }

    private void executeRequest(HttpUriRequest request, String url)
    {
        HttpClient client = new DefaultHttpClient();

        HttpResponse httpResponse;

        try {
            httpResponse = client.execute(request);
            responseCode = httpResponse.getStatusLine().getStatusCode();
            message = httpResponse.getStatusLine().getReasonPhrase();

            HttpEntity entity = httpResponse.getEntity();

            if (entity != null) {

                InputStream instream = entity.getContent();
                response = convertStreamToString(instream);

                // Closing the input stream will trigger connection release
                instream.close();
            }

        } catch (ClientProtocolException e)  {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        } catch (IOException e) {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        }
    }

    private static String convertStreamToString(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

Here is an example of how I use the class to call the Google Analytics API. I use the AddParam methods to add query string / post values and the AddHeader method to add headers to the request. RequestMethod is a simple enum with GET and POST values.

RestClient client = new RestClient(LOGIN_URL);
client.AddParam("accountType", "GOOGLE");
client.AddParam("source", "tboda-widgalytics-0.1");
client.AddParam("Email", _username);
client.AddParam("Passwd", _password);
client.AddParam("service", "analytics");
client.AddHeader("GData-Version", "2");

try {
    client.Execute(RequestMethod.POST);
} catch (Exception e) {
    e.printStackTrace();
}

String response = client.getResponse();

The class also exposes the Http response code and message which are important when using some Restful APIs. I know could definitely improve/extend on this code and would love to hear from those more experienced in Java and Android than myself.

Split String Into Array of Chunks

Here is a little function I needed to use today for spliting a string into an array of strings of a given length rather than by a particular character. I ran into a situation where the database columns I wanted to insert some text into were split over a number of columns eg “DescriptionLine1″, “DescriptionLine2″, “DescriptionLine3″.

Through the magic of extension methods I can split the string into chunks using this code.

            var splitItemDescription = item.Product.Description.SplitIntoChunks(40);

Here is the code for the extension method, written in C#.

        public static string[] SplitIntoChunks(this string toSplit, int chunkSize)
        {
            int stringLength = toSplit.Length;

            int chunksRequired = (int)Math.Ceiling((decimal)stringLength / (decimal)chunkSize);
            var stringArray = new string[chunksRequired];

            int lengthRemaining = stringLength;

            for (int i = 0; i < chunksRequired; i++)
            {
                int lengthToUse = Math.Min(lengthRemaining, chunkSize);
                int startIndex = chunkSize * i;
                stringArray[i] = toSplit.Substring(startIndex, lengthToUse);

                lengthRemaining = lengthRemaining - lengthToUse;
            }

            return stringArray;
        }

The method takes into account strings of which the length is not a factor of the chunk size being used by using what is remaing of the string for the last element of the array.

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.