Back to: ASP.NET Core Tutorials For Beginners and Professionals
Controllers in ASP.NET Core MVC Application
In this article, I will discuss the Controllers in ASP.NET Core MVC Applications with Examples. Please read our previous article discussing AddController() vs AddMvc() vs AddControllersWithViews() vs AddRazorPages() Methods in ASP.NET Core Web Application. Controllers are the brains of an ASP.NET Core MVC Application. As part of this article, we will discuss the following pointers.
- What is a Controller?
- How Does Controller Work in ASP.NET Core MVC?
- How do you add a Controller to the ASP.NET Core Application?
- What are Action Methods?
- How to Pass Parameters in Action Methods?
- How Controller Instance Created in ASP.NET Core MVC Application?
What is a Controller in ASP.NET Core?
A Controller is a special class in the ASP.NET Core Application with .cs (for C# language) extension. In the ASP.NET Core MVC Application, the controller class must be inherited from the Controller base class. In ASP.NET Core MVC, the Controller base class provides many properties, methods, and features that handle HTTP requests and produce responses in our application. It provides Action Result Methods, Model State Management, Validation, TempData, ViewBag, ViewData, etc. A controller is a class that:
- Inherits from the Controller base class.
- Contains action methods that respond to HTTP requests.
- Interacts with models to retrieve or update data.
- Selects views to render HTML or returns data directly.
How Controllers Work in ASP.NET Core?
Controllers in the MVC Design Pattern handle the incoming HTTP Request, work with the model, and select a view to render. When the client (browser) sends a request to the server, that request first goes through the request processing pipeline. Once the request passes the request processing pipeline (i.e., Middleware Component Registered into the Pipeline), it will hit the controller. Inside the controller, there are lots of methods (called action methods) that handle the incoming HTTP Requests. The action method inside executes the business logic and prepares the response, which is sent back to the client who initially requested it. For a better understanding, please have a look at the following diagram.
The Controllers in the ASP.NET Core MVC Application logically group similar types of actions together. This grouping of similar types of action together allows us to define sets of rules, such as caching, routing, and authorization, which will be applied collectively.
How do you add Controllers to the ASP.NET Core Application?
If you create the ASP.NET Core Application using the MVC Project Template, it will create HomeController within the Controllers folder by default. But if you create the ASP.NET Core Application with the Empty Project template, then by default, you will not find the Controllers folder in your project. As we discuss everything from scratch, we will create the ASP.NET Core Application with Empty Template and manually add the Controllers folder and the Controllers.
Step 1: Creating ASP.NET Core Empty Web Application
To create a new Empty ASP.NET Core Web Application, open Visual Studio 2022 and click the Create a new project tab, as shown in the image below.
Once you click on the Create a new project tab, the Create a new project window will open. Select the ASP.NET Core Empty project template in this window and click the Next button, as shown in the image below.
Once you click on the Next button, it will open the Configure Your New Project window. Here, you must provide the necessary information to create a new project. First, give an appropriate name for your project (FirstCoreMVCWebApplication), set the location where you want to create this project, and the solution name for the ASP.NET Core Web application. And finally, click on the Create button, as shown in the image below.
Once you click on the Next button, it will open the Additional Information window. Here, you need to select .NET Framework. You also need to check the Configure for HTTPS and do not use top-level statements check boxes. Finally, click the Create button, as shown in the image below.
Once you click the Create button, a new ASP.NET Core Web Application will be created in Visual Studio 2022 using .NET 8. The project will have the following file and folder structure.
Step 2: Adding Controllers Folder
Once you create the ASP.NET Core Empty Project, we need to add the Controllers folder to create our Controllers. To do so, right-click on the project and then select the add => new folder option from the context menu, which will add a new folder to your project. Just rename the folder as Controllers.
Step 3: Adding Controller in ASP.NET Core
Once you create the Controllers folder, we need to add a controller (StudentController) inside this Controllers folder. To do so, right-click on the Controller folder and select the Add => Controller option from the context menu, which will open the Add Controller window, as shown in the below image. Here, we will create the MVC Controller with the Empty template. So, select the MVC Controller – Empty option and click the Add button, as shown in the image below.
As you can see in the above image, we have three templates for creating an MVC controller. So you can use any of the following three templates:
- MVC Controller – Empty: It will create an Empty Controller.
- MVC Controller with read/write actions: This template will create the controller with five action methods to create, read, update, delete, and list entities.
- MVC Controller with views, using Entity Framework: This template will create an MVC Controller with actions and Razor views to create, read, update, delete, and list entities using Entity Framework.
Once you click on the Add button, it will open the below window where you need to select the Controller Class – Empty option and give a meaningful name to your controller. Here, I give the name as StudentController and click on the Add button. The Controller name should be suffixed with the word Controller.
Once you click the Add button, StudentController will be Added to the Controllers folder, as shown in the image below.
Understanding StudentController:
Now, let us understand the StudentController class and its different components. Open the StudnetController.cs class, and you should get the following default code.
As you can see in the above image, the StudentController class is inherited from the Controller base class. This controller base class is present in Microsoft.AspNetCore.Mvc namespace, which is why it imports that Microsoft.AspNetCore.Mvc namespace. Now right-click on the Controller base class and select Go to the definition, and you will see the following definition of the Controller class.
As you can see in the above image, the Controller is an abstract class having many methods (Json, View, PartialView, OnActionExecuting, ViewComponent, etc.) and properties (TempData, ViewBag, ViewData, etc.). The point that you need to remember is that these methods and properties will be used when we are working with ASP.NET Core MVC Application. Again, if you look, this Controller class is inherited from the ControllerBase class.
Let us see the ControllerBase class definition as well. Right-click on the ControllerBase class and select Go to definition, and you will see the following definition. Here, you will see the RequestData, Response, Request, ModelState, Routing, Model Binder, HttpContext, and many more properties and methods, which we will use as part of our ASP.NET Core MVC Application.
Rules for Controller:
- Naming Convention: Controllers are typically named with the suffix Controller, like HomeController or ProductController.
- Inheriting from ControllerBase: Controllers usually inherit from the ControllerBase or Controller class, which provides many methods and properties for handling requests and responses.
I hope you now have clarity on ASP.NET Core MVC Controllers. Let’s move forward and understand the next topic, Action Methods.
What are Action Methods?
All the public methods of a controller class are known as Action Methods. They are created for a specific action or operation in the application. The Controller class can have many related action methods. For example, adding a Student is an action. Modifying the student data is another action. Deleting a student is another action. So, all the related actions should be created inside a particular controller.
An action method can return several types. Let us modify the HomeController as shown below, where one method returns all the student details. Intentionally, we returned a string from this method, but as we progress in this course, we will discuss the real implementation of this method. But for now, we return a string just for learning purposes.
using Microsoft.AspNetCore.Mvc; namespace FirstCoreMVCWebApplication.Controllers { public class StudentController : Controller { public string GetAllStudents() { return "Return All Students"; } } }
How Do We Call an Action Method of a Controller?
When our application receives an HTTP Request, the controller action method handles it. So, when we say we are hitting a controller, we are hitting its action method. The default structure is http:domain.com/ControllerName/ActionMethodName.
As we are working with the development environment using Visual Studio, the domain name will be our local host with some available port numbers. So, if we want to access the GetAllStudents action method of the HomeController, then the URL: http://localhost:<portnumber>/student/GetAllStudents
Let us prove this. You will not get the output if you run the application and navigate to the above URL. This is because we created this project using the ASP.NET Core Empty Project template. By default, the Empty Project template will not add the required MVC Service and Middleware Components to the application processing pipeline.
Modifying the Program Class:
Open the Program.cs class file and then copy and paste the code below into it, adding the required MVC service to the dependency injection and the MVC middleware to the request processing pipeline.
namespace FirstCoreMVCWebApplication { public class Program { public static void Main(string[] args) { // Create a WebApplication builder, which provides various configuration settings // and services for the web application var builder = WebApplication.CreateBuilder(args); // Add MVC services to the service container. // This includes support for controllers and views. builder.Services.AddMvc(); // Build the application using the configured builder var app = builder.Build(); // Enable routing middleware, which matches incoming HTTP requests to endpoints defined in the application app.UseRouting(); // Map the default controller route (convention: {controller=Home}/{action=Index}/{id?}) // This means if no specific route is provided, it will default to HomeController and Index action app.MapControllerRoute( name: "default", // Name of the route pattern: "{controller=Home}/{action=Index}/{id?}" // URL pattern for the route ); // Run the application, which blocks the calling thread and starts listening for incoming HTTP requests app.Run(); } } }
With the above change in place, now run the application and navigate to the URL http://localhost:<portnumber>/student/GetAllStudents, and you should get the output as expected, as shown in the image below.
Please look at the following image to better understand how the above URL mapped to the Student Controller’s GetAllStudents action method.
How to Pass Parameters in Action Methods?
Let us understand this with an example. Now, we want to search for students based on their names. To do so, add the following action method inside the Student Controller.
public string GetStudentsByName(string name) { return $"Return All Students with Name : {name}"; }
Now run the application, navigate to the URL http://localhost:<portnumber>/student/GetStudentsByName?name=james, and see the output as shown in the below image.
In this case, the query string parameter name is mapped with the GetStudentsByName action method name parameter. In our upcoming articles, we will discuss parameter mapping, default mapping, and more.
When should we create a new controller?
Whenever we need to define a new group of actions or operations in our applications, we must create a new controller. For example, to do operations of students, we can create a Student Controller. To manage the security of your application, like login, logout, etc., you can create a Security Controller.
How Many Controllers can we have in a Single Application?
It depends on the application. At least one controller is required to perform operations. Maximum n number of Controllers we can have into one application.
How is Controller Instance Created in ASP.NET Core MVC?
We have discussed creating and using Controllers in ASP.NET Core MVC Applications. We also understand that the Controller Action Method will handle the incoming HTTP Request. But if you look at the controller, you will see that Controller is a class inherited from the Controller Base class, and this class has a method called Action Method.
We also know that if we want to invoke a method (non-static), then we need an instance of that class. Now, the question is, who, when, and how created the Controller class instance, and how is the action method called using that instance? Let us proceed and understand this with an example.
How is Controller Instance Created in ASP.NET Core MVC?
To create an ASP.NET Core MVC Application, we need to add the required MVC Services and Middleware Components into the Request Processing Pipeline. For example, you can add the MVC services using the following statement within your Main method of the Program.cs class file.
Then, we need to configure the MVC Middleware into the Request Processing Pipeline. For example, the following code will add the MVC Middleware Component to the Application Processing Pipeline.
So, in the ASP.NET Core MVC Web Application, the MVC Middleware Component receives an HTTP Request when the client sends an HTTP Request. Once the MVC Middleware Component receives the request, based on routing, it selects the controller and action method to execute.
However, in order to execute the action method, the MVC Middleware must create an instance of the selected controller. This makes sense, as we know that if we want to invoke a non-static method, we need an instance of the class. This is not different from executing a controller action method.
The MVC Middleware uses Reflection to create an instance of the Controller class. This will use the following IControllerActivator class. As you can see, this interface provides three methods: Create, Release, and ReleaseAsync.
object Create(ControllerContext context):
- This method creates an instance of a controller using the provided ControllerContext. The ControllerContext parameter provides contextual information about the current request and the controller being created. It includes information like the HTTP context, route data, and action descriptor (it contains detailed information about the action method, which the framework uses to process HTTP requests and route them to the appropriate action method). The method returns an instance of the controller.
- The ASP.NET Core framework calls this method to create a controller instance. The implementation can use the ControllerContext to determine how to create the controller, involving dependency injection or other custom logic.
void Release(ControllerContext context, object controller):
- This method is responsible for releasing a controller instance and providing a way to perform any necessary cleanup or disposal of the controller. The ControllerContext parameter provides contextual information about the current request and the controller being released. This object parameter is the instance of the controller that needs to be released. This method does not return a value.
- This method is called by the ASP.NET Core framework to release a controller instance after it has been used. The implementation can include any necessary cleanup or disposal logic, such as calling Dispose on the controller if it implements IDisposable.
ValueTask ReleaseAsync(ControllerContext context, object controller):
- This method is responsible for asynchronously releasing a controller instance. It provides a way to perform any necessary cleanup or disposal of the controller in an asynchronous manner. The ControllerContext parameter provides contextual information about the current request and the controller being released. The object parameter is the instance of the controller that needs to be released.
- The ASP.NET Core framework calls this method to release a controller instance after it has been used asynchronously. The implementation can include any necessary asynchronous cleanup or disposal logic.
DefaultControllerActivator
Now, the above interface is implemented by the DefaultControllerActivator class, which implements the IControllerActivator interface methods and provides the logic to create and release the controller. If you go to the definition of DefaultControllerActivator class, then you will see the following.
As you can see, this class provides implementations for the IControllerActivator interface methods. This is how the controller instance is created in the ASP.NET Core MVC Application.
In the next article, I will discuss Models in ASP.NET Core MVC with Examples. In this article, I try to explain ASP.NET Core MVC Controllers with examples. I hope you enjoy this ASP.NET Core MVC Controllers article.
very usefull guide
very good article
We have discussed how to Create and use Controllers in ASP.NET Core MVC Applications. We also understand that the Controller Action Method will handle the incoming HTTP Request. But if you look at the controller, you will see that it is a class inherited from the Controller Base class, and this class has a method called Action Method.
The above sentence is ambiguous. I believe it means that the controller classes (inheriting from ControllerBase) define action methods to handle specific requests. The base class ControllerBase provides the necessary infrastructure and utility methods to support the execution of these action methods.
I am a beginner, but I really like your articles. Perhaps my previous concerns were due to my level of programming skills.