One of the most interesting updates of the new ASP.NET Core platform (also known as ASP.NET 5) is the fact that it merges the old MVC and Web API frameworks into one (MVC 6). This allows you to have the best of both worlds: the rich features of the former MVC Controllers – with each methods returning an ActionResult – together with the versatility of the ApiControllers, whenever we need to return pure HTTP response types such as IHttpActionResult, HttpResponseMessage and so on. This basically means being able to serve Views and/or WebServices whenever we want to, without having to change your overall approach.

What if we need to do that in a plain old ASP.NET 4 MVC-based application? As a matter of fact, we can do that there too: any standard MVC Controller can be tweaked to make it act & behave just like an ApiController: we just need to develop our very own ActionResult classes and everything will more-or-less work like we’re expecting to. However, such an approach can be very hard to maintain and test: on top of that, having MVC Controllers methods returning ActionResult mixed with others returning raw/serialized/IHttpActionResult data can be very confusing from a developer perspective, expecially if you’re not working alone.

Luckily enough, there’s a nicer alternative: we can import (and properly configure) the core ASP.NET Web API package into our MVC-based Web Application: this way we’ll get the best of both worlds, being able to use the Controller and/or the ApiController classes together, as long as we need to. To do that, we just have to manually install the required components of the Web API framework that we normally miss in a MVC4 or MVC5 project. This post will explain how we can do that in few easy steps.

Install the Web API NuGet packages

The first thing to do is to install the latest version of the ASP.NET Web API package. We can do that by opening the Visual Studio’s Package Manager Console and issuing the following NuGetcommands:

1

2

>Install-PackageMicrosoft.AspNet.WebApi.Core

>Install-PackageMicrosoft.AspNet.WebApi.WebHost

For further references regarding ASP.NET Web API package we can also read we can refer to the official documentation.

Create a sample Web API Controller

Once we imported the required packages we can add an ApiController to our existing ASP.NET MVC project. The ApiControlleris the base class for the ASP.NET Web API controllers: the most relevant difference between a MVC Controllerand an ApiControlleris that the latter is specialized in returning data: just to make an example, they can transparently serializing the data into the format requested by the client. It’s also worth noticing that they follow a different routing scheme, providing REST-ful API routes by convention (that can be changed using Attribute-based routing, as explained here).

We can either copy the above code in our /Controllers/ folder or creating one from scratch to suit our needs.

Define a Web API Routing Configuration

The next step involves implementing Web API in our existing MVC-based routing configuration. We can do that in two ways: add a Web API configuration file (the suggested way) or override the existing routing configuration of our MVC Web Application.

Adding a WebApiConfig.cs file

If we want to enforce a “separation of concerns” between MVC and Web API, This is our best choice. From Solution Explorer, right-click to the /App_Start/ folder, then add a new C# class file naming it WebApiConfig.cs with the following contents:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

usingSystem.Web.Http;

publicstaticclassWebApiConfig

{

publicstaticvoidRegister(HttpConfiguration config)

{

// Web API routes

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(

name:"DefaultApi",

routeTemplate:"api/{controller}/{id}",

defaults:new{id=RouteParameter.Optional}

);

}

}

NOTE: In case you don’t have the /App_Start/ folder, any other folder will also work, as long as you’ll add the relevant namespace reference to the Global.asax.cs and/or Startup.cs file when you’ll have to register it (see below for details).

This will ensure that every requesting URL starting with /api/ will be routed to our Web API controllers and handled by them.

Adding a Web API rule to RouteConfig.cs file

Alternatively, we could also add a WebApi-specific rule to the RouteConfig.cs file, which controls the MVC routing rules. We can do that in the following way:

The benefit of doing that is that we can skip the following paragraph, as we don’t have anything new to register, at the cost of mixing the two. On the other hand, we’ll have the two worlds intertwined into one, which can lead to confusion. Altough this is mostly a developer choice, we slightly recommend the following approach.

Register the WebAPI Routing Configuration

If we chose to add a new WebApiConfig.cs file, we need to register that on our Web Application’s main configuration class. This is most likely the MvcApplication class within the Global.asax.cs file, which Application_Start method needs to be changed as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

protectedvoidApplication_Start()

{

// Register Web API routing support before anything else

GlobalConfiguration.Configure(WebApiConfig.Register);

// The rest of our file goes here

// ...

AreaRegistration.RegisterAllAreas();

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

RouteConfig.RegisterRoutes(RouteTable.Routes);

BundleConfig.RegisterBundles(BundleTable.Bundles);

// ...

}

If we’re using the OWIN Startup template instead, we need to do the same in the Configurationmethod of the Startup class, which is defined withinin the Startup.cs file:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

publicvoidConfiguration(IAppBuilder app)

{

// Register Web API routing support before anything else

GlobalConfiguration.Configure(WebApiConfig.Register);

// The rest of our file goes here

// ...

AreaRegistration.RegisterAllAreas();

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

RouteConfig.RegisterRoutes(RouteTable.Routes);

BundleConfig.RegisterBundles(BundleTable.Bundles);

ConfigureAuth(app);

// ...

}

Testing it up

That’s it. Now we have the best of both worlds into the same Web Application. We can easily test it up by requesting the following URLs:

1

2

3

/api/Sample/

/api/Sample/5

/api/Sample/Custom/

Notice the last URL: we added it as an example to demonstrate how is possible to mix the default Web API RESTful conventions with custom action methods using attribute-based routing.

Post navigation

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies.

This site uses cookies to improve user experience, personalize content & ads, provide social media features and analyze our traffic: some of these info are shared with our social media, advertising and analytics partners. We assume you're okay with this, but you can opt-out if you wish. Read the Privacy Policy for further info.