ASP.NET MVC vs Web API 2

In this article you will learn about the difference between ASP.NET MVC and Web API 2.

Introduction

In this article, I am going to highlight the differences between ASP.NET MVC Controllers and Web API 2.0 Controllers, illustrating that with samples of code. However, I will emphasize more on Web API 2.0 as it is the latest evolution in Microsoft web services toolkit.

Advantages of Web API over MVC Controllers

API Controllers decouples code from serialization of results:

Every method in Web API will return data (JSON) without serialization.

However, in order to return JSON Data in MVC controllers, we will set the returned Action Result type to JsonResult and call the Json method on our object to ensure it is packaged in JSON.

  1. public JsonResult GetBooks()  
  2. {  
  3.     var books = _repository.GetBooks();  
  4.     return Json(books, JsonRequestBehavior.AllowGet);  
  5. }  
Content negotiation:

Components called formatters serializes the data returned to the client. They are automatically selected based on the content of the Accept header of the incoming request. You can either use built- in formatter such as: JSON and Xml or replace them by modifying the configuration.

Content negotiation plays a role in simplifying the development of method that might return the same raw data in a variety of formats, most typically XML and JSON.

Hosting:

Web API controllers can be hosted outside ASP.NET Runtime Stack and IIS Web server (things WCF was able to do) and are mainly used to build restful services hosted by specific organization and can be consumed by any device (android, IOS, web or windows application).

MVC controllers typically rely on MVC framework and are built with the view in mind (mainly returning HTML to the browser).

Now, we will dig deeper into code and implementation and check the key differences:

Controllers

MVC controllers uses the base class Controller which is defined in System.Web.Mvc while API uses ApiController which is defined in System.Web.Http
  1. public class BooksController: Controller  
  2. {  
  3.     public ActionResult Details(int id)  
  4.     {  
  5.         var book = _repository.GetBook(id);  
  6.         if (book == null) returnnewHttpNotFoundResult();  
  7.   
  8.         return View(book);  
  9.     }  
  10. }  
Web API will resolve our objects to the suitable format using content negotiation. In this example the book object is converted to JSON and sent back as a response to the incoming request:
  1. public class Books Controller: ApiController  
  2. {  
  3.     public Book GetById(int id)  
  4.     {  
  5.         var book = _repository.GetBook(id);  
  6.         if (book == null) thrownewHttpResponseException(HttpStatusCode.NotFound);  
  7.         return book;  
  8.     }  
  9. }  
Web API Controllers by default dispatch to actions by HTTP verbs. Action names will start with one of the verb names (GET, PUT, POST, and DELETE). For instance, Get, GetBooks, and GetById will map to the verb name “GET”.

For actions that don’t match with one of those verbs, the default verb supported will be “POST”. Thus, we have to decorate all the actions that don’t meet with this naming conventions by one of the following attributes:
  • HttpGet
  • HttpPut
  • HttpPost
  • HttpDelete

MVC Controllers by default dispatch actions by name. A specific action name in a controller will directly map to the URL.

The two routes (routes configuration are explained later in this article) to the actions in the previous code will be the following:

  • /api/books/{id}will route to ASP.NET Web API,where /api will occupy the URI space by default for all actions, followed by controller name and the parameter expected.
  • /books/details/{id} will route to ASP.NET MVC (as ControllerName/ActionName/{parameter}).

Action Return Values

MVC controller methods returns objects of types of ActionResult that can produce variety of results. These are some of the predefined action results in ASP.NET MVC:

Action Result Behavior
ContentResult Sends raw data to the browser. It serialize any content it receives.
FileContentResult Sends the content of the file to the browser.
FileStreamResult Sends the content of the file to the browser (which is represented using Stream object).
HttpNotFoundResult Sends HTTP 404 response code (Resource was not found).
HttpUnauthorizedResult Sends HTTP 401 response code (Unauthorized request).
JavaScriptResult Sends JavaScript content to the browser.
JsonResult Sends JSON result to the browser.
ViewResult Send HTML content to the browser and represents a page view.
PartialResult Sends HTML content to the browser that represents a part of the whole page view.

On the other hand, Web API 2.0 can return:

  • HttpResponseMessage:

    Raw objects (when passing domain models) are converted automatically to the suitable format (JSON or XML) using Content Negotiation which is a Web API feature. However, it is difficult to return different representation of success and errors in the response and this will make unit testing more difficult.
    1. publicHttpResponseMessage Get()   
    2. {  
    3.     //Retrieve a list of books from the DB  
    4.     IEnumerable < Book > books = _repository.GetBooks();  
    5.   
    6.     //Write the list to the response body.  
    7.     HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, books);  
    8.     return response;  
    9. }  
  • IHttpActionResult:

    Introduced in Web API 2.0 and will simplify unit testing controllers by returning a value type of IHttpActionResult. The ApiController includes many methods that directly return those action Results which sounds like MVC controller.
    1. publicIHttpActionResult Get()   
    2. {  
    3.     // Get a list of books from the DB.  
    4.     IEnumerable < Book > books = _repository.GetBooks();  
    5.     if (books == null)  
    6.     {  
    7.         return NotFound();  
    8.     }  
    9.     // Returns an Ok Negotiated ContentResult  
    10.     return Ok(books);  
    11. }  

The following are the methods in the ApiController that return action results:

Method Behavior
BadRequest Returns an HTTP 400 (“Bad Request”)
Conflict Returns an HTTP 409 (“Conflict”)
Content Returns Content (which is automatically negotiated or specified by the developer as media type formatter or content type)
Created Returns an HTTP 201
InternalServerError Returns an HTTP 500 (“Internal Server Error”)
Json Returns an HTTP 200 (“OK”) and provides the content formatted in JSON
NotFound Returns an HTTP 404 (“Not Found”)
Ok Returns an HTTP 200 (“OK”)
Redirect Returns an HTTP 302 (“Found”)
ResponseMessage Returns the provided HttpResponseMessage
StatusCode Returns a response with provided HTTP status code and an empty response body
Unauthorized Returns an HTTP 401 (“Unauthorized)

Configuration

Web API 2.0 is designed not to have static global variables (as in traditional ASP.NET Applications where they share application configuration in Global.asax). Routes are defined in the WebApiConfig static class and puts its configurations into the HttpConfiguration object and its Route property.

  1. publicstaticclassWebApiConfig  
  2. {  
  3.     //Routing configuration for Web API  
  4.     public staticvoid Register(HttpConfiguration config)   
  5.     {  
  6.         config.Routes.MapHttpRoute(  
  7.             name: "DefaultApi",  
  8.             routeTemplate: "api/{controller}/{id}",  
  9.             defaults: new   
  10.             {  
  11.                 id = RouteParameter.Optional  
  12.             }  
  13.         );  
  14.     }  
  15. }  
On the other hand, MVC routes are defined in the static RouteConfig class, directly against the System.Web.RouteCollection.
  1. public class RouteConfig   
  2. {  
  3.     public staticvoid RegisterRoutes(RouteCollection routes)  
  4.     {  
  5.         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  6.   
  7.         routes.MapRoute(  
  8.             name: "Default",  
  9.             url: "{controller}/{action}/{id}",  
  10.             defaults: new  
  11.             {  
  12.                 controller = "Home", action = "Index", id =  
  13.                     UrlParameter.Optional  
  14.             }  
  15.         );  
  16.     }  
  17. }  
Now, let’s take a look on the Global.asax file where we have to register our Web API Configuration by passing the parameter GlobalConfiguration.Configuration to the register method.

Also, you can see how RouteConfig can add the routes to the Route table for MVC.
  1. protected void Application_Start()  
  2. {  
  3.     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  4.   
  5.     //configuring the WebApi by calling Register method and passing the   
  6.     paramerter  
  7.   
  8.     WebApiConfig.Register(GlobalConfiguration.Configuration);  
  9.     RouteConfig.RegisterRoutes(RouteTable.Routes);  
  10.     BundleConfig.RegisterBundles(BundleTable.Bundles)  
  11.     AuthConfig.RegisterAuth();  
  12. }  
Conclusion

While MVC controllers can be consumed as services and do anything with additional coding, its main purpose is to build web HTML applications with some Ajax functions returning JSON data. On the other hand, Web API 2.0 is dedicated and specialized with transferring data and will be the optimal choice and the suitable development model that makes it easy to build RESTful services interface to different clients running on different platforms.