I am following this tutorial for creating an ASP.NET Core Web API, and in the section on adding a controller, the tutorial gives code to replace the template code for a controller. One of the things that really caught my eye was that in the template code, I get:
TodoController : Controller
Then in the tutorial code I'm supposed to use instead of that, I find:
[Route("api/[controller]")] [ApiController] TodoController : ControllerBase
I'm very interested to know why it is necessary to derive from ControllerBase
instead of Controller
for a Web API controller. Why is this done?
Web API controller is a class which can be created under the Controllers folder or any other folder under your project's root folder. The name of a controller class must end with "Controller" and it must be derived from System. Web.
The ApiController attribute is commonly coupled with the ControllerBase class to enable REST-specific behavior for controllers, and it allows us to build HTTP APIs. First of all, it provides implicit model state validation, which means that we do not need to explicitly check the ModelState.
The Web API returns the data in various formats, such as JSON, XML and other format based on the accept header of the request. But the MVC returns the data in the JSON format by using JSONResult. The Web API supports content negotiation, self hosting. All these are not supported by the MVC.
The ControllerBase Class in ASP.NET Core provides many methods and properties to handle HTTP Requests and Responses. For example, if you want 200 Status codes from your action method, this provides one method.
When you write an API then ControllerBase matches your requirements better but both will work. Don't create a web API controller by deriving from the Controller class. Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests.
API Controllers – Creating API in ASP.NET Core. API controllers are just like regular controllers except that their action methods produce responses which contain data objects and are sent to the client without HTML markup. Since not all clients are browsers so to provide them with data we your API Controllers.
As of Core 2.0, your MVC and API controllers both derive from the Controller class, which derives from ControllerBase: As of Core 2.1 (and 2.2), the template-generated classes look a little different, where a Web controller is a child of the Controller class and an API controller is a child of ControllerBase.
Don't create a web API controller by deriving from the Controller class. Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests. There's an exception to this rule: if you plan to use the same controller for both views and web APIs, derive it from Controller.
why it is necessary to derive from
ControllerBase
instead ofController
for a Web API controller.
It is not strictly necessary, just more to the point. The Controller
class derives from ControllerBase
and adds some members that are only needed to support Views.
Basically:
public abstract class Controller : ControllerBase { public dynamic ViewBag { get; } public virtual ViewResult View(object model) { } // more View support stuff }
When you write an API then ControllerBase matches your requirements better but both will work.
Per the documentation (emphasis mine):
Don't create a web API controller by deriving from the Controller class. Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests. There's an exception to this rule: if you plan to use the same controller for both views and web APIs, derive it from Controller.
I seem to remember that there was no ControllerBase in the first MVC iterations, it was inserted later. Hence the slightly odd naming/inheritance structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With