I love the fact that ASP.NET Core's MVC6 merged the two patterns into one because I often need to support both worlds. While it's true that you can tweak any standard MVC Controller
(and/or develop your own ActionResult
classes) to act & behave just like an ApiController
, it can be very hard to maintain and to test: on top of that, having 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 and need to bring other developers to speed with that hybrid approach.
The best technique I've come so far to minimize that issue in ASP.NET non-Core web applications is to import (and properly configure) the Web API package into the MVC-based Web Application, so I can have the best of both worlds: Controllers
for Views, ApiControllers
for data.
In order to do that, you need to do the following:
- Install the following Web API packages using NuGet:
Microsoft.AspNet.WebApi.Core
and Microsoft.AspNet.WebApi.WebHost
.
- Add one or more ApiControllers to your
/Controllers/
folder.
- Add the following WebApiConfig.cs file to your
/App_Config/
folder:
using System.Web.Http;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Finally, you'll need to register the above class to your Startup class (either Startup.cs
or Global.asax.cs
, depending if you're using OWIN Startup template or not).
Startup.cs
public void Configuration(IAppBuilder app)
{
// Register Web API routing support before anything else
GlobalConfiguration.Configure(WebApiConfig.Register);
// The rest of your file goes there
// ...
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureAuth(app);
// ...
}
Global.asax.cs
protected void Application_Start()
{
// Register Web API routing support before anything else
GlobalConfiguration.Configure(WebApiConfig.Register);
// The rest of your file goes there
// ...
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// ...
}
This approach - together with its pros and cons - is further explained in this post I wrote on my blog.
ApiController
andController
so if you're using the newer .NET you don't need to worry about ApiController anymore - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api – Simon_Weaver