Using Web API only on ASP.NET Core – Without MVC specific stuff
Web API vs MVC
MVC and Web API have many things in common. Things like filters, attributes, controllers. Since MVC and Web API share so many things with ASP.NET Core we got these two unified into one framework.
ASP.NET Core is the new ASP.NET framework. And you can use it to build web applications. If you want to use a framework like MVC and get a lot of “opinionated” features then you would use ASP.NET Core MVC.
ASP.NET Core MVC is a framework that builds on top of ASP.NET Core and it includes both MVC and Web API.
If you want to use MVC (and Web API) you will add Microsoft.AspNetCore.Mvc package. However, that adds a lot of MVC specific stuff. Here is the list of packages that Microsoft.AspNetCore.Mvc includes
- Microsoft.AspNetCore.Mvc.ApiExplorer(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.Cors(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.DataAnnotations(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.Formatters.Json(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.Localization(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.RazorPages(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.TagHelpers(>= 2.0.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures(>= 2.0.0)
- Microsoft.Extensions.Caching.Memory(>= 2.0.0)
- Microsoft.Extensions.DependencyInjection(>= 2.0.0)
As you can see from the list this includes Razor Pages, Tag Helpers, View Features. It’s quite obvious that for pure REST you don’t want these included.
If we check the code for the internal AddMvc extension we can see these things clearly:
public static IMvcBuilder AddMvc(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } var builder = services.AddMvcCore(); builder.AddApiExplorer(); builder.AddAuthorization(); AddDefaultFrameworkParts(builder.PartManager); // Order added affects options setup order // Default framework order builder.AddFormatterMappings(); builder.AddViews(); builder.AddRazorViewEngine(); builder.AddRazorPages(); builder.AddCacheTagHelper(); // +1 order builder.AddDataAnnotations(); // +1 order // +10 order builder.AddJsonFormatters(); builder.AddCors(); return new MvcBuilder(builder.Services, builder.PartManager); }
Now you are thinking; for Web API I probably need JSON Formatters and Cors. However, you would also need MvcCore. This includes stuff like routing, attributes, filters, result executors, model binders, controllers etc.
Basically, stuff required for both MVC and Web API.
AddMvcCore is another built-in extension method that returns IMvcCoreBuilder.
So, to include Web API only you will install Microsoft.AspNetCore.Mvc.Core package. However, if you want CORS features with your Web API (and you probably want) you need to install Microsoft.AspNetCore.Mvc.Cors package. You probably want formatters for JSON input and output. That’s what Microsoft.AspNetCore.Mvc.Formatters.Json package adds.
You could also add Microsoft.AspNetCore.Mvc.ApiExplorer. Although, that’s if you want to use it. That’s if you wanna use the tool like Swagger or anything that does describe API endpoints in an application.
So, three packages that you usually require for Web API:
- Microsoft.AspNetCore.Mvc.Core
- Microsoft.AspNetCore.Mvc.Cors
- Microsoft.AspNetCore.Mvc.Formatters.Json
Now, my ConfigureServices would look a bit different.
Here is how Startup class looks:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; namespace AspNetCoreWebAPIOnly { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var mvcCoreBuilder = services.AddMvcCore(); mvcCoreBuilder .AddFormatterMappings() .AddJsonFormatters() .AddCors(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMvc(); } } }
Now we have core things that are required for both Web API and MVC. However, we don’t have MVC specific features.
There is one more thing that you need to be aware. When you are doing controllers in your application, the Controller parent class will not be available. You need to use ControllerBase class. And that is a base class for an MVC controller without view support.
Regular Controller class uses ControllerBase and adds some View specific features. Here is an overview of Controller class:
So, we don’t really want that in our Web API project, so we will use ControllerBase class.
Here is an example of the controller:
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; namespace AspNetCoreWebAPIOnly.Controllers { [Route("api/[controller]")] // ControllerBase instead of Controller public class ValuesController : ControllerBase { // GET api/values [HttpGet] public IEnumerable<string> Get() { return new[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public string Get(int id) { return "value"; } // POST api/values [HttpPost] public void Post([FromBody]string value) { } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 [HttpDelete("{id}")] public void Delete(int id) { } } }
Code Sample
You can find the code sample on GitHub – AspNetCoreWebAPIOnly.