Tell me about the apicontrollerattribute in ASP. NET Core MVC2.1

Source: Internet
Author: User
Post the article Link body first

ASP. NET Core MVC 2.1 intentionally provides some small features for building the HTTP API, and today the protagonist is ApiControllerAttribute . (Note: The article is February 18, so the article mentions that core2.1 has not yet been released).

0. Apicontrollerattribute inherits from Controllerattribute

ASP. NET Core MVC already has controllerattribute, which is used to label whether a type is a controller. After labeling, the framework knows which controllers are inside the system. (The framework also has other ways to get the controller inside the program, so this controllerattribute is not required).

ApiControllerAttributeis a ControllerAttribute subclass, so the framework is the same as the tagged object when dealing with the controller discovery ControllerAttribute .

However, because the ApiControllerAttribute IApiBehaviorMetadata interface is implemented, some additional features are provided with the HTTP API as a starting point. These features are described below.

1. Automatic Model State Verification

This is the point, and the framework will help you automatically verify the model's state, which is ModelState . ( Note: However, I just found this article because I used the fluentvalidation model to verify that the problem was not used.

The framework will automatically register for you ModelStateInvalidFilter , which will run in the OnActionExecuting event (specifically: After the model is bound before the action executes). He will check internally ModelState if it is valid, and if invalid will return directly to the badrequest, there is no need to execute the subsequent code to improve efficiency.

It automatically puts the model state into the response, and the content type is application/problem+json . Of course you can also customize, because after all you will have your own verification, after the text will speak.

Next, let's give an example to say.

    • The previous wording
[Route("[controller]")]public class BookController : Controller{    [HttpPost("")]    public IActionResult PostBook([FromBody]Book book)    {        if (ModelState.IsValid) //判断状态        {            return BadRequest(ModelState);        }        //其他代码。。。    }}
    • I can write this now.
[ApiController][Route("[controller]")]public class BookController : Controller{    [HttpPost("")]    public IActionResult PostBook(Book book)    {        //直接写,不用验证modelstate    }}

By the way, ModelStateInvalidFilter it's a public class, so you don't have to ApiControllerAttribute use it.

2. Automatic inference of parameter binding policy

Another very useful feature is that the model binding of the parameters inside the action can be inferred automatically.

There is an annoying problem with ASP. NET Core MVC you need to specify this feature manually for parameters so that the [FromBody] system knows how to deserialize them from the request body, such as deserializing JSON. Therefore, many third-party libraries have been written to solve this problem, such as:

    • WebApiContrib.Core.Formatter.Bson
    • WebApiContrib.Core.Formatter.Csv
    • The others do not write, for example

Now, these can be resolved automatically.

In addition, if a parameter is defined in the route, he will automatically binate from the path, that is, the URL to try to bind, not the words will be bound from the query parameters. IFormFlieThe default is obtained from the form form bindings.

Here's a look at the code:

    • Before
[Route("[controller]")]public class BookController : Controller{    [HttpPost("")]    public IActionResult PostBook([FromBody]Book book)    {        // 写代码    }}
    • Right now
[ApiController][Route("[controller]")]public class BookController : Controller{    [HttpPost("")]    public IActionResult PostBook(Book book)//FromBody没必要写了    {        // 写代码    }}
3. Handling multipart/form-dataRequest

If a parameter in your action specifies an [FromFile] attribute (which is usually used for file uploads), the framework automatically assumes that the request is multipart/form-data . This is to solve the problem raised in the community.

But this is also optional, as long as you define it yourself on the action [Consumes(...)] .

4. Other

There are two points of note:

    1. The visibility of the apiexplorer. All controller pairs are visible by default ApiExplorer , so the generation of swagger is not affected.
    2. It's just a feature-based route. The centralized routing mechanism does not apply to the API controller, and the framework requires that only attribute-based routing be used, that is, the way specified on the action [Route("XXX")] .
5. Custom Behavior

Like most components of the MVC framework, ApiControllerAttribute the behavior is highly customizable. First of all, most of what is said above can be easily switched on/off.

The specific settings are implemented in the Startup method ApiBehaviorOptions , first look at this class.

    public class ApiBehaviorOptions    {        public Func<ActionContext, IActionResult> InvalidModelStateResponseFactory { get; set; }        public bool SuppressModelStateInvalidFilter { get; set; }        public bool SuppressInferBindingSourcesForParameters { get; set; }        public bool SuppressConsumesConstraintForFormFileParameters { get; set; }    }

All attributes of type bool are false by default. Suppres has the meaning of stopping. You can set it in the following ways.

services.Configure<ApiBehaviorOptions>(options =>{    options.SuppressModelStateInvalidFilter = true;    options.SuppressConsumesConstraintForFormFileParameters = true;});

To take a look at the InvalidModelStateResponseFactory property, he is a return IActionResult func, through which we can inject our own delegate to implement the required return type, for example.

  services. configure<apibehavioroptions> (Options =>{options. Invalidmodelstateresponsefactory = Actioncontext = {var errors = actioncontext.modelstate. Where (e = e.value.errors.count > 0). Select (e = new Error {Name = E.key, Message = E.value.errors.first (). ErrorMessage}).         ToArray ();    return new Badrequestobjectresult (errors); }});     Class Error{public string Name {get; set;} public string Message {get; set;}}  
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.