27

When I create a new controller in the API project, it generates a controller class with [ApiController] attribute, like this:

[ApiController]
public class TestController : ControllerBase
{
 //implementation
}

I've seen a few webapi projects where usage of this attribute is omitted. Microsoft documentation here says:

Indicates that a type and all derived types are used to serve HTTP API responses. The presence of this attribute can be used to target conventions, filters and other behaviors based on the purpose of the controller.

But still, I don't get the idea. Can someone explain what is the purpose of this attribute with the real-life example?

2
  • Check out this for a real-life example and the accepted answer for further insight. Commented Dec 2, 2018 at 11:27
  • 1
    Always check the documentation, its all pretty well documented. It just adds additional conventions for WebApi controllers, which makes sure you have to use less attributes to describe it (FromBody attribute becomes optional, model validation happens automatically etc) Commented Dec 2, 2018 at 13:36

1 Answer 1

44

This is well-explained in the docs: Annotation with ApiController attribute, which explains that adding the [ApiController] attribute to a controller does the following:

  1. Automatic HTTP 400 responses

    Adds an action filter that returns a 400 response if ModelState.IsValid is false.

  2. Binding source parameter inference

    Changes model-binding conventions. For example, [FromBody] is inferred for complex-type parameters.

  3. Multipart/form-data request inference

    Infers a Content-Type of multipart/form-data for parameters marked with [FromForm].

  4. Attribute routing requirement

    Mandates that all actions must be attribute-routed.

You can see how this is actually done in the source:

foreach (var actionModel in controllerModel.Actions)
{
    if (!isApiController && !actionModel.Attributes.OfType<IApiBehaviorMetadata>().Any())
    {
        continue;
    }

    EnsureActionIsAttributeRouted(controllerHasSelectorModel, actionModel);
    AddInvalidModelStateFilter(actionModel);
    InferParameterBindingSources(actionModel);
    InferParameterModelPrefixes(actionModel);
    AddMultipartFormDataConsumesAttribute(actionModel);
}

If you're not interested in any of the features described above, you can omit the attribute. It's also possible to suppress individual features by configuring the ApiBehaviorOptions class.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.