Using the WCF Web API in an ASP.NET MVC application

Warning: This post is based on a prerelease version of the WCF Web API

 

In my previous blog post I showed how to add to and use the new WCF Web API a console application using NuGet. Now that works but it is far more likely that you will want to be using IIS and host the REST service as part of a web application. So in this blog post I am going to show how to do the normal thing Smile

 

I Created an ASP.NET MVC 3 app to host the REST service. Not that there is anything specific to MVC I need here, all I need is a web site and I could have started with a WebForms application just the same. I just prefer the MVC approach, you might not.

 

Just like in this post we can add a reference to the WCF Web API to our project. Just like in the post the best package to start with is the WebApi.All.

 

The service we are going to host is pretty simple for now. All we can do is retrieve a list of books or get an individual one. In future blog posts we are going to expand on that and make our service more interesting. For now the service looks like this:

[ServiceContract]


[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]


public class BooksService: IDisposable


{


    private readonly IBooksRepository _repo;


 


    public BooksService(IBooksRepository repo)


    {


        _repo = repo;


    }


 


    public BooksService()


        : this(new BooksRepository())


    {


    }


 


    [WebGet(UriTemplate = "")]


    List<Book> GetBooks()


    {


        var result = _repo.GetBooks();


        return result;


    }


 


    [WebGet(UriTemplate = "/{id}")]


    Book GetBook(int id)


    {


        var result = _repo.GetBook(id);


        return result;


    }


 


    public void Dispose()


    {


        if (_repo != null)


        {


            _repo.Dispose();


        }


    }

A few interesting things to note here:

  • We are using the standard WCF ServiceContract attribute to indicate this is a service.
  • We are using the AspNetCompatibilityRequirements to make sure the service runs as part or the ASP.NET pipeline. This means we can use the ASP.NET routing engine.
  • The individual service operations are decorated with the WebGet attribute specifying the UriTemplate. Note that you can set the RequestFormat and ResponseFormat on the WebGet attribute but this is completely ignored. Request and Response formats are done a different way, more about that in a future blog post.
  • The OperationContract attribute is not used as we are not going to expose these operations using SOAP.

Next we need to make sure we actually host the service so clients can call into it. There are several ways we can do this. For example we can create a ServiceRoute() and add it to the routes collection like so:

public static void RegisterRoutes(RouteCollection routes)


{


    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


 


    routes.Add(new ServiceRoute("books", new HttpServiceHostFactory(), typeof(BooksService)));


 


    routes.MapRoute(


        "Default", // Route name


        "{controller}/{action}/{id}", // URL with parameters


        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults


    );


}

This works fine for our simple service but a far better approach is to use an IHttpHostConfigurationBuilder create our service host for us. Right now that doesn’t buy is much but it will allow us to easily add functionality to the HttpServiceHost in future blog posts. So instead of the code above I am going to use the code below to do the same:

public static void RegisterRoutes(RouteCollection routes)


{


    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


 


    var builder = HttpHostConfiguration.Create();


    routes.MapServiceRoute<BooksService>("books", builder);


 


    routes.MapRoute(


        "Default", // Route name


        "{controller}/{action}/{id}", // URL with parameters


        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults


    );


}


These steps, and adding the required IBooksRepository and its implementation, result in a working service the URL “books” maps to the collection of all books and the URL “books/3” maps to the book with id 3 using the template. Navigating to the URL in browser results in the following:

image image

 

Pretty nice Smile

 

A non browser client application can consume this REST service quite easily using a standard HTTP API available. For example using a HttpWebRequest like this:

var request = HttpWebRequest.Create("http://localhost:28330/books");


var response = request.GetResponse();


 


var reader = new StreamReader(response.GetResponseStream());


Console.WriteLine(reader.ReadToEnd());

or even simpler using a WebClient like this:

var client = new WebClient();


Console.WriteLine(client.DownloadString("http://localhost:28330/books"));




Both will produce exactly the same XML being printed.



 



Download the source code.



 



Enjoy!



 



[f1]
[f2]

One thought on “Using the WCF Web API in an ASP.NET MVC application

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>