Post navigation

Client side support with the ASP.NET Web API

With REST there is not a lot required on the client as far as sending requests goes. As long as you can send HTTP GET requests you are good to go and there are very few programming stacks that don’t allow for some form of doing that. Of course just doing an HTTP GET is going to give you some data back and you still have to understand that data but that is an application specific issue.

In order to make life even easier the ASP.NET Web API adds some client support in the form of the HttpClient class. But first lets see what happens if we just hit an ASP.NET Web API endpoint with a simple client.

I am using Entity Framework Code First here and the model and context look like this:

1:publicclass Product

2: {

3:publicint ProductID { get; set; }

4:publicstring ProductName { get; set; }

5:publicdecimal UnitPrice { get; set; }

6: }

7:

8:publicclass NorthwindContext : DbContext

9: {

10:public DbSet<Product> Products { get; set; }

11: }

And the ASP.NET Web API controller looks like this:

1:publicclass ProductsController : ApiController

2: {

3:private NorthwindContext _db = new NorthwindContext();

4:

5:// GET /api/<controller>

6:public IEnumerable<Product> Get()

7: {

8:return _db.Products.ToList();

9: }

10:

11:// GET /api/<controller>/5

12:public Product Get(int id)

13: {

14:return _db.Products.Single(p => p.ProductID == id);

15: }

16:

17:protectedoverridevoid Dispose(bool disposing)

18: {

19:if (disposing && _db != null)

20: {

21: _db.Dispose();

22: _db = null;

23: }

24:base.Dispose(disposing);

25: }

26: }

Given that the Web API supports returning both XAML and JSON it would appear the following code would work just fine.

Unfortunately it doesn’t and we receive an XmlException with the message “Data at the root level is invalid”. The reason is that the XElement sends the request to the server without specifying an accept header. And where in the previous WCF Web API this would have worked because XML was the default type if nothing was specified this has changed. With the ASP.NET Web API the default is JSON. So this request returns a JSON data stream the XElement can’t handle. What we need to do is specify we want XML using the HTTP Accept header. There are different ways we can do this but here I am going to the the client side support in the form of the HttpClient.

Using the HttpClient

First we need to add a NuGet package named System.Net.HTTP that contains the required classes

With that in place we can start using the HttpClient instead. The code is a bit longer but that is mainly because we still need to set the HTTP Accept header to return XML instead of the default JSON

This code might seem a bit verbose but that is mainly because the client is real simple and uses POX and therefore a StreamContent. There are also richer ways of doing so with declared types and the ObjectContent<T>. The result is a predictable OK status with the new product being added to the database.

Of course this should really have been a 201 Created with the URL pointing to the location of the new resource but we still need to look at how to control the response message from the ApiController.