Microsoft Recently released ASP.NET MVC 4 beta. However the Beta comes with a go live license, meaning you can use it in production systems. There are various articles on it starting with Scott Gu’s introduction to Scott Hanselman’s primer, describing all the features of MVC 4. In short, it’s a gold mine of new features and we could go on an on with them. But instead of talking about all the features, we are going to go piecemeal and take one feature at a time and approach it from various angles.
Today, we will see what it takes to use the newly launched WebAPI in an existing MVC 3 application by upgrading it to MVC 4 and extending it to provide http services using the WebAPI. (If you want to look at the WebAPI sample only you can jump here)
What is WebAPI
The WebAPI framework provides quite a few things making web based services development smoother. Its major claim to fame is it’s direct support for HTTP Verbs (GET, PUT, POST, DELETE) that helps you implement services directly over HTTP. This greatly opens up the different types of clients that can use your services. Let me clarify with an example:
Today a web solution is difficult to imagine without supporting multitude of clients apart from the browser. It could be a Windows client application; it definitely could be a mobile application, which could in turn be built on multiple platforms (WP7, iOS, Android, Blackberry etc. etc.) and with the popularity of Macs, who knows you even might want to support OSX clients. Previously the way to do it would be to implement XML SOAP based web services. XML Web Services though great (and better than proprietary RPC services), it always had a ‘bolt on’ feel with all the overhead involved to set Web Services to work on HTTP. In short, putting up web services was a non-trivial amount of work.
The WebAPI framework aims to simplify this, by providing easy mapping of HTTP verbs to services for your applications. So practically any client that supports HTTP can avail of your applications services. All they need to know is the correct HTTP URL.
Apart from supporting HTTP verbs directly, it supports HTTP content negotiation, support for cross cutting concerns (ala Action Filters in MVC) and self-hosting (meaning no compulsion of IIS/ASP.NET dependency).
A very good starting point for learning more is the official ASP.NET Web-API Site. We will go ahead now and see how to add WebAPI based service support to an existing MVC web application.
Update: Also see how the same WebAPI can be consumed from a Windows and WinRT Client Application
Installing ASP.NET MVC4
To start off with, you will need MVC4 Beta. You can install it from here. Remember it’s still a beta. So make sure you have a decent ‘rollback’ option (Windows Restore Point or VMWare Snapshot or your favorite backup strategy). However it does not ‘upgrade’/’overwrite’ MVC3, it installs side-by-side so you have both MVC3 and the MVC4 Beta.
Once the installer completes, reboot if required and we are all set.
Upgrading an existing MVC3 Application
We take our FunWithSignalRDI project from the Dependency Injection Article and ‘upgrade’ it. Upgrade path is not automatic, so we will do it manually, which basically means create a new project and add the existing files.
Note 1: Reading the previous article is not compulsory if you are okay with generic DI concepts and understand what Composition Root means.
Note 2: I picked the example because keeping DI in the mix helps demonstrate an additional WebAPI feature. Also SignalR is not the topic of discussion in this article today, though I expect that functionality to continue working.
Step 1: Open the FunWithSignalDI.sln
Step 2: Add a new Project, select ASP.NET MVC 4
Step 3: Select the Web API template
The new project looks very similar to an existing MVC 3 boilerplate, except for an additional controller called ValuesController. When we open the ValuesController class we see this class inherits from the new ApiController instead of the MVC Controller class.
Step 4: Copy the HomeController and BlogPostController from the RaBlog project to RaBlog.Web project.
Step 5: Next Copy the BlogPost folder from Views of the existing project to the new project.
Step 6: Copy the BlogControllerFactory and CompositionRoot classes
Step 7: Hook up the ControllerFactory in Global.asax
Step 8: Right Click on the solution and Select ‘Manage NuGet Packages for the Solution’. Lookup up the SignalR dependency and click on ‘Manage’.
Step 9: Select the FunWithSignalRDI.Web project so that the SignalR dependencies get added to the new project as well.
Step 10: Copy the diff_patch_match.js from the scripts folder, and the SignalR folder with the BlogHub class to the new Web project so that the SignalR sample continues to work
Step 11: Add reference to the RaBlog.Domain project. Copy the ‘BlogPostRepositoryType’ AppSetting and the ‘FunWithSignalR’ connection string from the original Web.Config to the new Web.Config.
Step 12: Copy the Post-Build event from the FunWithSignalR project to the FunWithSignalR.Web project. This ensures the Data dll is available at runtime.
That should be it. Build and Run. The SignalR app is now using MVC 4!
Adding WebAPI Support to our MVC Application
The Web Api project template already added a default ValuesController. Now let’s say we want to develop our WebAPI to enable end clients List, Read and Update Posts into our app. This would be for developers who want to create third part client apps.
Step 1: We will rename the ApiController to DevController. As a result our WebAPI methods will be available at
Based on whether you are using, the GET, POST or PUT verb appropriate methods will be called.
Step 2: Add a constructor that takes a single parameter of type IBlogPostRepository and save it locally
Step 3: Implement the Get(), Get(id), Post(…) and Put(…) methods as follows.
For the Post, Put and Delete methods we have a return type of HttpResponseMessage. Each of the responses has appropriate HTTP statuses so that the calling client can easily identify the outcome of the action. No special parsing required. As we can see above we don’t want users to be able to Delete any of our posts using the API so we are sending back status code Forbidden (HTTP status code 403) telling users they cannot Delete using this API.
The Get method returns a Generic HttpResponseMessage<T> where T is the type of object you want to return. In the above implementation we have checked if the id being passed fetches us some value, if yes, we send HTTP status code 200 (Ok), if not we send back HTTP status code 404 (Not Found).
Step 4: With the ApiController setup we could run the application but on trying to access the Api we would get an error. Any guesses? Yes, just like MVC’s default controller factory, WebAPI by default, doesn’t accept controllers with parameterized constructors. As a result we will need to leverage WebAPI’s extensibility framework to inject our repository into the DevController.
WebAPI Extensibility and Dependency Resolution
The WebAPI team thought through most of the scenarios in which it would be used in and one of the most common ways to do it would be in DI scenarios where either we could be using an IoC container or use our hand built CompositionRoot. Enter the built in Service Locator aka GlobalConfiguration.Configuration.ServicerResolver and the SystemWeb.Http.Services.IDependencyResolver.
The ServiceResolver class is an implementation of the Service Locator pattern whose sole aim is to find dependent services. In our case we can use the SetResolver method and pass an Instance of a class that implements IDependencyResolver.
- We add a class WebApiDependencyResolver to the FunWithSignalRDI.Web application and implement it as follows:
- IDependency Resolver has two methods, GetService and GetServices both of which pass the serviceType it is looking for.
- We pass the repository instance via the constructor.
- In the GetService method we check if the type the service locator is looking for is DevController and if it is, instantiate it using the repository and return it. If not, return null so that the Service Locator can continue looking for that type in other registered service providers.
- The GetServices method just returns a default list of objects.
Updating the CompositionRoot
We have the WebApiDependencyResolver, but going by our DI principles we shouldn’t be ‘new-ing’ it up randomly. We would like the CompositionRoot class doing the creation for us. So we update the CompositionRoot class as follows:
- We declare a second readonly variable for the dependency resolver.
- We split the repository instantiation and the dependency instantiation.
- The InitializeRepository() method returns us the instance of IBlogRepository implementation. It uses the BlogRepositoryType app setting to get the Type name and then generate it using Reflection.
- We then instantiate the BlogControllerFactory and the WebApiDependencyResolver using the repository object.
Hooking up the Dependency Resolver
The dependency resolver only needs to be hooked up when the application starts. So we update the Global.asax as follows:
- We add a method RegisterDependencies() and instantiate the CompositionRoot.
- Call ServiceResolver.SetResolver(…) method with instance of the DependencyResolver from CompositionRoot.
- Similarly set the MVC ControllerFactory using the ControllerFactory from the CompositionRoot.
- Call RegisterDependencies() from Application_Start()
This completes our implementation and we can now expect WebAPI framework to do it’s magic when we hit the URLs of our application.
To try it out
- Launch the application and create a couple of posts
- Now Hit F12 to bring up the Developer Tools in IE or any of your favorite Browser Dev tool. For IE, go to the Network Tab and click Start Capturing
- Type this URL in the browser window http://localhost:<port number>/api/dev. IE’s ‘download bar’ will come up at the bottom of the screen. Click on the ‘Go To Detailed View’ button. Select the Response Body. You will see the JSON equivalent of the posts, that looking something like the follows:
- By default our browsers do a http GET when we hit a URL and since there were no further parameters WebAPI mapped it to the Get method call without parameters that gets all the Posts available
- To get a particular Post append /<id> to the above URL like the following
- So there you have it, we just used WebAPI to expose our little application’s Create, Read, Update and List functionalities, while preventing people from calling Delete. Now we can go ahead and create any type of client that can do HTTP Get/Post/Put etc. and manipulate content in our web app.
In Web 2.0 public facing web apps are ever increasingly interconnected through web-based services. The WebAPI now enables ASP.NET applications to provide a cross platform lightweight framework that help developers easily setup such services.
In an enterprise world, inter-app communication just got a whole lot easier.
This concludes our introductory article for ASP.NET MVC4 Beta covering some features of the WebAPI. We will be following up with more discovering more features as we go.
The entire source code of this article can be downloaded over here