A while ago we looked at how ApiControllerAttribute can be used in ASP.NET Core MVC to make Web API authoring a little bit more developer friendly.
Today let’s have a look at a tiny little improvement in ASP.NET Core 2.2 - the ability to set it up globally (and perhaps a few other things).
Global set up of [ApiController] π
As a quick reminder, ApiControllerAttribute enables a couple of MVC behaviors/features which are geared towards HTTP API development. AMong those are, for example, automatic model state validation or automatic injection of the [FromBody] attribute onto the action parameters.
The normal usage of the attribute is to place it on the controller as shown on the next snippet.
[ApiController]
[Route("[controller]")]
public class BookController : Controller
{
[HttpPost]
public ActionResult<Book> PostBook(Book book)
{
// omitted from brevity
}
}
Now, that’s all fine, but what happens if you’d like to avoid having to put it all over the place on every controller and have it globally enabled for all of the controllers? Well, the only reasonable solution in ASP.NET Core 2.1 was to put it on a base class and make all your controllers inherit from that class.
ASP.NET Core 2.2 comes with a little improvement in that area. Turns out that, in a rather unusual way for something that’s part of an MVC configuration, you could actually register [ApiController] at an assembly (!) level.
This is done as a typical assembly attribute and can be placed anywhere in an assembly. For example:
[assembly: ApiController]
namespace MyNamespace
{
public class Startup
{
//omitted for brevity
}
}
The above setup will automatically propagate the [ApiController] feature to all controllers discovered in this assembly.
Unfortunately, there is still no way to dynamically register the attribute, for example using IApplicationModelConvetion or some sort of a filter - it must be done statically.
ApiBehaviorOptions customization improvements π
One additional improvement worth mentioning, that also shipped in ASP.NET Core 2.2, is a small change around customization of ApiBehaviorOptions (so really the customization of the [ApiController] feature behavior).
Previously you had to do it by using the usual Configure
In ASP.NET Core MVC 2.2 customization of ApiBehaviorOptions can be done via an extension method on IMvcBuilder or IMvcCoreBuilder - and this is actually the recommended approach going forward. This is shown next:
// ASP.NET Core MVC 2.1
services.AddMvc();
services.Configure<ApiBehaviorOptions>(o =>
{
o.InvalidModelStateResponseFactory = context =>
{
var error = new
{
Detail = "Custom error"
};
return new BadRequestObjectResult(error);
};
};
// ASP.NET Core MVC 2.2
services.AddMvc().ConfigureApiBehaviorOptions(o =>
{
o.InvalidModelStateResponseFactory = context =>
{
var error = new
{
Detail = "Custom error"
};
return new BadRequestObjectResult(error);
};
});
This way you will not have to worry anymore about adding the Configure