joe.mcbride

Adventures in Silverlight, Windows Phone 7, WPF, and ASP.NET MVC

Consuming WCF Web (REST) Apis in Silverlight

Microsoft, including the MEF Master Glenn Block, is hard at work trying to provide an easier way to create RESTful web services.  You can currently see the progress of their work on Codeplex, http://wcf.codeplex.com/ Unfortunately they currently do not support Silverlight or Windows Phone 7 clients to access the services in a friendly manor.

To that end, I created a 'SimpleHttpClient' which can be used in Silverlight to access a WCF Web Api.  It currently can be found as a fork of the WCF HTTP Contrib project.  Silverlight does not provide the ability to create your own custom query provider, so this 'SimpleHttpClient' and classes do not use LINQ directly, though the API is fairly similar (using extension methods).  The client & helper libraries were written from scratch with no direct dependencies on the core http framework.  I'm currently also working on a WP7 compatible version.  If you're interested in seeing improvements to this or have any suggestions I'd love to hear them.  Hopefully this helps in your quest to write and consume REST Apis in Silverlight.

EDIT: Vote up Silverlight support for WCF REST at the codeplex site! http://joem.me/fnKy5Q EDIT2: Note that for this to fully work with Preview 3, make sure you have this patch http://wcf.codeplex.com/Thread/View.aspx?ThreadId=242523 And the UriTemplateOperationSelector changes from this changeset: http://wcf.codeplex.com/SourceControl/changeset/changes/c4e21202c82d

Get Source: https://hg01.codeplex.com/forks/xamlcoder/wcfhttpcontrib

Here are a few sample queries:

// Get all people
SimpleHttpClient client = new SimpleHttpClient("http://localhost:1182/people");
// can also use MediaType.Json, which is the default
client.Accept = MediaType.Xml;

var query = client.CreateQuery<Person>();

HandleQuery(query);
// Get person by ID
int id;

if (Int32.TryParse(this.uxPersonID.Text, out id))
{
    SimpleHttpClient client = new SimpleHttpClient("http://localhost:1182/people");

    var query = client.CreateQuery<Person>().Where(c => c.ID, id);

    HandleQuery(query);
}
// Get top 3 people
SimpleHttpClient client = new SimpleHttpClient("http://localhost:1182/people");

var query = client.CreateQuery<Person>().Take(3);

HandleQuery(query);
// Get 3rd person
SimpleHttpClient client = new SimpleHttpClient("http://localhost:1182/people");

var query = client.CreateQuery<Person>().Skip(2).Take(1);

HandleQuery(query);
// Handle query method used above
private void HandleQuery(HttpQuery<Person> query)
{
    var task = query.ExecuteAsync();
    task.ContinueWith(t =>
    {
        Execute.OnUIThread(() =>
        {
            if (!t.IsFaulted && t.IsCompleted && t.Result != null)
            {
                t.Result.Apply(p => { Debug.WriteLine("Person: {0}", p); });
            }
        });
    });
}
// Create new person
Uri uri = new Uri("http://localhost:1182/people");

SimpleHttpClient client = new SimpleHttpClient(uri.ToString());

var contact = new Person { ID = 5, Name = personName.Text };

var stream = contact.WriteObjectAsXml();

var request = new HttpRequestMessage(HttpMethod.Post);
request.Accept = MediaType.Xml;
request.ContentType = MediaType.Xml;
request.RequestUri = uri;
request.Content = stream;

var task = client.SendAsync(request);
task.ContinueWith(t =>
{
    Execute.OnUIThread(() =>
    {
        var person = t.Result.ReadXmlAsObject<Person>();

        if (person != null)
        {
            Debug.WriteLine("Person: {0}", person);
        }
    });
});