There are many ways to expose functionality and data from a server to a client. And there is probably almost as many going the other way… In Microsoft scenarios, using WCF is the obvious choice for most of us, and when people talk WCF, they generally talk SOAP based webservices.
SOAP can however be a less than ideal choice in a some cases. It is way more complicated than some of the other options, and on top of that it has a tendency to bloat the messages being sent, which can be an issue when working with mobile clients for example.
REST on the other hand is a pretty neat way of doing it. It uses open HTTP standards, making it available to all types of clients, even through a browser if needed. It is also very lightweight as the request and response are stripped down to the bare essentials, and can be made even smaller by using Json. And if you don’t like Json, you can still just use POX (plain old xml).
The only downside to using REST is the fact that we generally don’t get a nice proxy that serialize and de-serialize the data for us, and tells ut what methods are available. Instead we have to handle all of that manually, which can be cumbersome.
The goal for this post is to show how easily we can expose, and consume, REST in a simple and structured way using WCF WebApi and in this case Silverlight. The Silverlight end can of course be any .NET-based client…
The first thing needed to get this going is to install the “Portable Class Libraries” VS extension from http://msdn.microsoft.com/en-us/library/gg597391.aspx. It is an extension to Visual Studio 2010 SP1 that makes it possible to create library projects that can be used in different platforms such as Silverlight, .NET and XNA without having to create a separate project for each platform. The only limitation is that you can only use namespaces available in all the platforms, which means a lot fewer than you would get if you had the whole framework. It is however more than enough to create DTO (Data Transfer Object) classes, which is exactly what I am going to do here…
Once that is installed, I start up a new Silverlight Application project in Visual Studio. I also let VS create a new ASP.NET MVC project to host it. It is important to use an MVC project, otherwise you will have to make some changes to the Web Application to support Url routing… At least I think so…
Once the 2 projects have been created, I create a new Portable Class Library project, which is the new project type created by the previous install.
Inside the PCL project, I create the DTO:s I need. For this demo, that means one class called called AddUserCommand, one called UpdateUserCommand and one called User. The commands are sent from the client to tell the server to do something, and the User class is used to transfer the data about a User from the server to the client…
They look like this
public class AddUserCommand
{
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
public class UpdateUserCommand
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
And no, they aren’t brilliant in any way. They aren’t even that well thought through, but they will do for this demo…
Once the DTO:s have been created, I add a reference to the PCL project from both my Silverlight application and my MVC application.
Next I want to create the REST API that the client will consume. For this, I use WCF WebApi, which makes this really easy.
Installing WebApi is easily done through NuGet, just search for WebApi in the NuGet Package Manager. WebApi will also install the HttpClient NuGet package. Unfortunately, this package isn’t available in Silverlight…but I will get back to that…
As soon as the WebApi NuGet package is installed, I create a new class called Service in my MVC project, and put it in a folder called Api, but you are free to name it whatever you want and place it wherever you want… The name and location isn’t important. What is important is that I adorn the class with a ServiceContractAttribute like this
[ServiceContract]
public class Service
{
// TODO: Implement
}
But before I go and create the implementation of the service, I open the Global.asax.cs file and add the following to the RegisterRoutes() method
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Added code
routes.Add(new ServiceRoute("api", new HttpServiceHostFactory(), typeof(Api.Service)));
// End of added code
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
This extra added route makes sure that all calls coming to “/api” will be routed to the service I just created. It is also possible to configure WebApi to enable a built-in “test client” that enables you to call methods on in the API from the browser in a simple way for debugging and things. But this is outside the scope of this post.
Now that I got the route set up, I can go back to the Service.cs file and add the required functionality.
As you might have understood from the names of the commands I created in the PCL project, I will be adding, updating and getting users from the service. However, in this demo, there will be no database or anything, instead I will just store the users in a dictionary. You will just have to imagine the database… 
I start with the “get” method, which is easy to implement. I create a new method called GetUser, that takes an int called id and returns an instance of HttpContent. I then adorn it with a WebGetAttribute, setting the UriTemplate to “user/{id}”, like this
[ServiceContract]
public class Service
{
private static Dictionary<int, User> _users = new Dictionary<int, User>();
[WebGet(UriTemplate = "user/{id}")]
public HttpContent GetUser(int id)
{
// TODO: Implement
}
}
If you have done ASP.NET MVC development, you will recognize format of the UriTemplate. If you haven’t, all you need to know is that it defines what paths the method will handle, and by adding curly-brace-enclosed parameters, you can read out parts of the path and get it sent to the method as parameters. In this case, anything added after “/api/user/” will be considered a user id and has to be possible to parse to an int.
The actual implementation of the method is just as simple as you would expect. It reads the user from the dictionary and returns it wrapped in a class inheriting from HttpContent called ObjectContent. But I also want to make sure that I provide a good RESTful API and return a 404 if there is no user with the specified id. Figuring out whether or not there is a user with the specified id is easy, but the question is how you return a 404. Luckily, that is easy, just throw a new HttpResponseException, passing a HttpStatusCode value to the constructor. So the actual implementation looks like this
[WebGet(UriTemplate = "user/{id}")]
public HttpContent GetUser(int id)
{
if (!_users.ContainsKey(id))
throw new HttpResponseException(HttpStatusCode.NotFound);
return new ObjectContent(typeof(User), _users[id], "application/json");
}
The ObjectContent object makes sure that the object is serialized correctly. In this case I tell it specifically that I want Json. Otherwise it creates XML by default…
You could change the method to return a User object straight up. The reason I am not doing that in this case has to do with Silverlight, but won’t be shown in this post. But here is the reason… Silverlight only gets a 404 whenever something goes wrong on the client. To solve this I generally have an “envelope” message that is passed back from method. The “envelope” contains an error code. So instead of using the proper RESTful way, and sending status codes, I send a proper 200 result all the time, but include the error in the message.
If you aren’t using Silverlight, or communicate in a way that accepts other status codes, I suggest just returning a User object…
The add and update methods are pretty much the same. The only real difference is that I add a WebInvokeAttribute instead of a WebGetAttribute. WebInvoke is used when you want to use HTTP PUT or POST instead of GET. Unfortunately there are some problems with using PUT in Silverlight, so I defined them both to use POST, but with different Uri:s.
[WebInvoke(UriTemplate = "user/add", Method = "POST")]
public HttpContent AddUser(AddUserCommand cmd)
{
var user = new User
{
Id = _users.Count + 1,
Name = cmd.Name,
Email = cmd.Email,
Age = cmd.Age
};
_users.Add(user.Id, user);
return new ObjectContent(typeof(User), user, "application/json");
}
[WebInvoke(UriTemplate = "user/update", Method = "POST")]
public HttpContent UpdateUser(UpdateUserCommand cmd)
{
if (!_users.ContainsKey(cmd.Id))
throw new HttpResponseException(HttpStatusCode.NotFound);
var user = _users[cmd.Id];
user.Name = cmd.Name;
user.Email = cmd.Email;
user.Age = cmd.Age;
return new ObjectContent(typeof(User), user, "application/json");
}
Well, there is one more difference. The parameter sent to the method is not part of the Uri as it is a post, instead I just declare the type I want as a parameter and WebApi automatically maps the posted data just like MVC does for you. And in this case, the parameters come from the PCL created previously, which will also be used on the client side.
Now that the server side is done, it is time to look at the Silverlight client.
As mentioned previously, there is no implementation of the HttpClient for Silverlight, so I will have to build something useful on my own. It just happens the be fairly simple though… But first I need another NuGet package. This time it is Json.NET that needs to be added to the Silverlight project. Once that is done, I can go on and build my own HttpClient, which I call RestClient for some reason…
The RestClient class will take a “base url” to the service in the constructor, and expose a generic Get and Post method that will be responsible for getting objects from the service, as well as send objects to it. When doing this, it takes the path to the method as a parameter, as well as an instance of the object to send.
The base of the RestClient looks like this
public class RestClient
{
private readonly Uri _baseAddress;
public RestClient(string baseAddress)
{
_baseAddress = new Uri(baseAddress);
}
public void Get<T>(string commandPath, Action<Exception, T> callback)
{
var client = new WebClient();
client.Headers[HttpRequestHeader.Accept] = "application/json";
DownloadStringCompletedEventHandler handler = null;
handler = (s, e) =>
{
client.DownloadStringCompleted -= handler;
if (e.Error != null)
{
callback(e.Error, default(T));
return;
}
var result = Deserialize<T>(new StringReader(e.Result));
callback(null, result);
};
client.DownloadStringCompleted += handler;
client.DownloadStringAsync(new Uri(_baseAddress, commandPath));
}
public void Post<T>(string commandPath, object data, Action<Exception, T> callback)
{
var synchContext = System.Threading.SynchronizationContext.Current;
var request = WebRequest.Create(new Uri(_baseAddress, commandPath));
request.Method = "POST";
request.ContentType = "application/json";
request.BeginGetRequestStream(iar =>
{
var reqStr = request.EndGetRequestStream(iar);
SerializeObject(data, reqStr);
request.BeginGetResponse(iar2 =>
{
WebResponse response;
try
{
response = request.EndGetResponse(iar2);
}
catch (Exception ex)
{
synchContext.Post((state) => callback((Exception)state, default(T)), ex);
return;
}
var result = Deserialize<T>(new StreamReader(response.GetResponseStream()));
synchContext.Post((state) => callback(null, (T)state), result);
}, null);
}, null);
}
// Serialization...
}
That was a LOT of code…I know…but it is fairly basic. It uses a WebClient to get a string from the server in the GET scenario, and a WebRequest when posting data to the server. The only 2 non-standard things are the serialization and deserialization of the objects being sent and received, as well as the fact that I store the SynchronizationContext in the post scenario to make sure I make the callback on the same thread as I started the post…
The serialization and de-serialization is ridiculously simple using Json.NET. The methods look like this
private static void SerializeObject(object data, Stream stream)
{
var serializer = new JsonSerializer();
var sw = new StreamWriter(stream);
serializer.Serialize(sw, data);
sw.Flush();
sw.Close();
}
private static T Deserialize<T>(TextReader reader)
{
var serializer = new JsonSerializer();
return serializer.Deserialize<T>(new JsonTextReader(reader));
}
As soon as the RestClient is built, I can build a simple UI to take the required input.
As this UI is ugly and simple, I won’t cover the actual UI and let you look at it in the download instead. But I will cover the ViewModels quickly…
The CreateUserViewModel exposes Name, Email and Age as public properties that are bound using TwoWay bindings. It also exposes an ICommand that does the actual creation by creating a new AddUserCommand, populate its properties and send it to the server using the RestClient’s Post method.
var cmd = new AddUserCommand {Name = Name, Email = Email, Age = Age};
var client = new RestClient(GetServiceUrl());
client.Post<User>("api/user/add", cmd, (ex, user) =>
{
if (ex != null)
return;
NavigateToNextPage()
});
As you can see, using the RestClient makes using RESTful APIs a breeze. You don’t have to care about serialization and stuff like that. Both the server and client can work with “real” objects and just ignore the whole transport part…
On the other page, “edit page”, I use the RestClient once again to get the User to edit, as well as to post the changes back to the server. Getting the user is really simple as well
int userId = GetUserId();
var c = new RestClient(GetServiceUrl());
c.Get<User>("api/user/" + userId, (ex, user) =>
{
if (ex != null)
return;
_user = user;
OnPropertyChanged(string.Empty);
});
That’s it! The only thing I want to mention is one more neat thing that a lot of people have seemed to have missed. That is the method called GetComponents() on the Uri class. It makes it really easy to get only the parts you need from a full Uri without having to do a bunch of string manipulation. Just tell it what parts you need using an enumeration called UriComponents. And since the UriComponents enumeration is a flags enum, you can just combine the values how you want. In this case, I need the scheme, server and port to get the host Url. Using GetComponents() that looks like this
Application.Current.Host.Source.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)
Previously I would have done something ugly like
var host = new Uri(Application.Current.Host.Source.ToString().Replace(Application.Current.Host.Source.LocalPath.ToString(), ""));
Or at least something similar. And it works, but it is really ugly…
That was it for this time! I really hope that this will help some of you getting started with RESTful APIs in Silverlight. It is really not that hard, and it makes for a really open and friendly API. Not to mention that it is easy to “debug” by just browsing to it…either by browsing to “Get methods” or by using the built-in test client in WebApi…
Code is obviously available for download: DaksideCookie.Ag.RestDemo.zip (4.95 mb)
Sorry for the large download. It is all the NuGet stuff. But I didn’t want to remove that and leave a half-working app…
That’s all folks! Cheers!