ASP Design Pattern
ASP Design Pattern
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:11 / 03:1110 Sec
How Does MVC Design Pattern Work in ASP.NET Core?
Let’s look at an example to understand how the MVC Design Pattern works in an ASP.NET
Core MVC application. For example, we want to design an application that displays the
student details on a web page, as shown below.
The Controller is the Component in the MVC design pattern that handles the incoming
request. The controller components do several things to handle the request. The controller
component creates the model that is required by a view. The model is the component in the
MVC design pattern, which basically contains classes that are used to store the domain data
or, you can say, business data. In the MVC design pattern, the Model component also
contains the required logic to retrieve data from a database.
Once the controller creates the model, it selects a view to render the domain or model data.
While selecting a view, it is also the controller’s responsibility to pass the model data. In the
MVC design pattern, the view’s only responsibility is rendering the model data. So, in MVC,
the view is the component responsible for generating the necessary HTML to render the
model data. Once the view generates the HTML, that HTML is sent to the client over the
network who initially made the request.
The three major components of an ASP.NET Core MVC Application are the Model, View, and
Controller. Let’s discuss each component of the MVC design pattern in detail.
Role of Model in MVC Design Pattern:
The Model in an MVC application represents the application’s state and business logic. That
means the Model is the component in the MVC Design pattern used to manage the data, i.e.,
the application’s state in memory. The Model represents a set of classes used to describe
the application’s validation, business, and data access logic. So, in our example, the model
consists of Student and StudentBusinessLayer classes.
Student.cs
namespace ASPNETCoreMVCApplication.Models
{
public class Student
{
public int StudentID { get; set; }
public string? Name { get; set; }
public string? Gender { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
}
3
}
StudentBusinessLayer.cs
namespace ASPNETCoreMVCApplication.Models
{
public class StudentBusinessLayer
{
public IEnumerable<Student> GetAll()
{
//logic to return all employees
return new List<Student>();
}
public Student GetById(int StudentID)
{
//logic to return an employee by employeeId
Student student = new Student()
{
StudentID = StudentID,
Name = "James",
Gender = "Male",
Branch = "CSE",
Section = "A2",
};
return student;
}
public void Insert(Student student)
{
//logic to insert a student
}
public void Update(Student student)
{
//logic to Update a student
}
public void Delete(int StudentID)
4
{
//logic to Delete a student
}
}
}
In our example, we use the Student class to hold the student data in memory. The
StudentBusinessLayer class manages the student data, performing the CRUD operation,
Validating the Student data, etc.
So, in short, we can say that a Model in the MVC Design Pattern contains a set of classes
used to represent the data and the logic to manage those data. In our example, the Student
class represents the data. The StudentBusinessLayer class manages the student data, i.e.,
validating the data and storing it in the database.
Role of View in MVC Design Pattern:
The View is the Component in the MVC Design pattern that contains the logic to represent
the model data as a user interface with which the end-user can interact. Basically, the view
renders the domain data (i.e., business data) provided to it by the controller. There should be
minimal logic (you should not write any business logic, calculation logic, etc.) within views,
and any logic in them should only be related to presenting the content.
For example, we want to display Student data on a web page. In the following example, the
student model carried the student data to the view. As already discussed, the view’s one and
only responsibility is to render the model data, in this case, student model data. The following
code does the same thing.
@model ASPNETCoreMVCApplication.Models.Student
<html>
<head>
<title>Student Details</title>
</head>
<body>
<br />
<br />
<table>
<tr>
<td>Student ID: </td>
<td>@Model.StudentID</td>
</tr>
<tr>
<td>Name: </td>
<td>@Model.Name</td>
5
</tr>
<tr>
<td>Gender: </td>
<td>@Model.Gender </td>
</tr>
<tr>
<td>Branch: </td>
<td>@Model.Branch</td>
</tr>
<tr>
<td>Section: </td>
<td>@Model.Section </td>
</tr>
</table>
</body>
</html>
Role of Controller in MVC Design Pattern:
The Controller is the component in an MVC application that handles the incoming HTTP
Request. Based on the user action, the respective controller might work with the model, select
a view to render the information, and then send the response back to the user who initially
made the request. So, the Controller is the component that will interact with both the models
and views to control the application execution flow.
In ASP.NET Core MVC Application, a Controller is a .cs (for C# language) file with some
methods called Action Methods. When a request comes on the controller, the controller’s
action method handles those requests. In our example, when the user issued a request, the
following URL
https://localhost:7132/Student/Details/2
Then, that request is mapped to the Details action method of the Student Controller. How will
it map to the Details Action Method of the Student Controller that will be discussed in our
upcoming articles. For now just look at the following Controller code:
using ASPNETCoreMVCApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace ASPNETCoreMVCApplication.Controllers
{
public class StudentController : Controller
{
public ActionResult Details(int studentId)
6
{
StudentBusinessLayer studentBL = new StudentBusinessLayer();
Student studentDetail = studentBL.GetById(studentId);
return View(studentDetail);
}
}
}
As you can see in the example, the Student Controller creates the Student object within the
Details action method. So, here, the Student is the Model. The controller uses the
StudentBusinessLayer class to fetch the Student data from the database.
Once the controller creates the Student model with the necessary student data, it passes the
Student model to the Details view. The Details view then generates the necessary HTML to
present the Student data. Once the HTML is generated, it is sent to the client over the network
who initially made the request.
Note: The Controller and View depend on the Model in the MVC Design Pattern, but the
Model never depends on either View or Controller. This is one of the main reasons for the
separation of concerns, which allows us to build and test the model independently of the
visual presentation.
What is ASP.NET Core MVC?
ASP.NET Core MVC is a Web Application Development Framework provided by Microsoft as
part of the ASP.NET Core platform. ASP.NET Core MVC framework is used for building Web
Apps using the Model-View-Controller (MVC) Design Pattern. So, you need to make it clear
that MVC is a Design Pattern, and ASP.NET Core MVC is the Framework based on MVC
Design Pattern.
Features of ASP.NET Core MVC:
The ASP.NET Core MVC Framework is comes with some of the amazing features. They are
as follows:
It is Open Source:
The ASP.NET Core MVC Framework is open source, which is the main reason for its
popularity. The Entire Source Code of ASP.NET Core MVC Framework is available
at https://github.com/aspnet, and you are free to download the source code; even if you
want, you can also modify and compile your own version.
Cross-Platform:
The ASP.NET Core MVC Framework is designed from scratch to be cross-platform for
development and deployment. You can develop Web Applications using ASP.NET Core MVC
Framework and Visual Studio Editor using Windows, Linux, and macOS. Visual Studio works
only on Windows and macOS. For Linux, you can use Visual Studio Code editor. Similarly,
you can deploy the ASP.NET Core MVC application in different server such as IIS, Apacha,
etc.
Extensible Framework:
ASP.NET Core MVC is highly extensible. You can make applications that can be extended
to any level in the future. Key features of this framework that give it the extensible power are:
1. View Components
2. Tag Helpers
7
3. Routing
Testing Made Maintainability:
The ASP.NET Core MVC Framework is an excellent choice for a maintainable and testable
application. It allows you to divide various parts of your application into separate and
independent components, which can be tested individually. You can easily integrate testing
frameworks like xUnit, MSTest, and MOQ to test different scenarios.
When to Choose ASP.NET MVC and When to Choose ASP.NET Core
MVC?
ASP.NET MVC:
1. If you are currently working on an existing application with ASP.NET MVC
and would like to expand the functionalities by adding new features.
2. If your team is familiar with ASP.NET MVC Framework but has yet to gain
experience with ASP.NET Core MVC.
3. If you want, your application will only be compatible with devices and servers
that run on the Windows operating system.
ASP.NET Core MVC:
1. If you have a preference for utilizing a framework that is completely open
source.
2. If you want your application to be able to be developed and hosted on any
operating system.
3. If your team members have knowledge of ASP.NET Core MVC.
4. If you are looking for an application development framework with a long
development roadmap ahead of it. If you look at the road map of .NET,
Microsoft has already provided it for the next five years.
AddController vs AddMvc vs AddControllersWithViews
vs AddRazorPages
Different MVC Services Methods Available in ASP.NET Core:
Let us understand the differences between AddController, AddMvc,
AddControllersWithViews, and AddRazorPages in ASP.NET Core Application.
Go to the definition of the AddMvc() Extension Method. You will see that along with
the AddMvc() method, AddController(), AddControllersWithViews(), and
AddRazorPages() methods are also available, as shown in the below image. All these
methods are implemented as an extension method on the IServiceCollection interface. And
further, each method has two overloaded versions available. One overloaded version does
not take any parameter, while the other overloaded version takes the Options object as the
parameter using which you can customize the service.
8
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:06 / 03:1110 Sec
Let us discuss each of these methods and the features they provide in detail. For a better
understanding, please have a look at the following image.
Antiforgery: This feature is unavailable in the AddControllers method and is available for the
other three methods. To prevent CSRF (Cross-Site Request Forgery) attacks, ASP.NET Core
MVC uses anti-forgery tokens, also called request verification tokens.
TempData: This feature is unavailable in the AddControllers method and is available for the
other three methods. TempData in ASP.NET Core MVC can be used to store temporary data,
which can be used in the subsequent request.
Views: This feature is unavailable in the AddControllers method but available for the other
three methods. A view is a user interface that displays data from the model to the user,
enabling the user to modify the data.
Pages: The Pages are available only with AddMVC and AddRazorPages methods.
Razor Pages are designed for page-focused scenarios; each page can handle its own model
and actions.
Tag Helpers: Tag Helpers are not available in the AddControllers method and are available
for the other three methods. Tag Helper is a new feature in ASP.NET Core MVC that enables
the server-side code to create and render HTML elements.
Memory Cache: The Memory Cache feature is also not available in the AddControllers
method but is available with the other three methods. Memory Cache is used to cache data
within the web server’s memory where your application is running. This in-memory cache can
significantly improve the performance and scalability of your application by temporarily storing
frequently accessed data, such as data from a database or web service.
Which Method to Use in Our Application?
This depends on which type of application you want to create.
1. If you want to create a Web API Application, i.e., Restful Services, without
views, you must use the AddControllers() extension method.
2. If you want to work with the Razor Pages Application, you need to use
the AddRazorPages() extension method in your Main method of the Program
class.
3. If you want to develop a Web Application using the Model View Controller
Design Pattern, you need to use the AddControllersWithViews() extension
method. Further, if you want Razor Pages features in your MVC application,
you must use the AddMVC method.
Note: The AddMvc method has all the features. You can use this AddMVC method with any
application (Web API, MVC, and Razor Pages). Adding the AddMvc() method will add extra
features even though they are not required for your application, which might impact the
performance of your application. So, depending on the requirement, you must choose the
appropriate method.
point and is responsible for selecting which model types to work with and which view to render
(i.e., it controls how the app responds to a given HTTP request).
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, it will
hit the controller. Inside the controller, there are lots of methods (called action methods) that
actually handle the incoming HTTP Requests. The action method inside the controller
executes the business logic and prepares the response, which is then sent back to the client
who initially made the request. For a better understanding, please have a look at the following
diagram.
Conquering the clouds on a journey to Ta Xua with the team - Road Trip Vietnam Team
- Nếm TV00:19 / 02:5410 Sec
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, it will open the Create a new project window.
You need to select the ASP.NET Core Empty project template from 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.
12
Once you click on the Next button, the Additional Information window will open. Here, you
need to select .NET 6.0 as the Framework, check the Configure for HTTPS and do not use
top-level statements check boxes, and finally click the Create button, as shown in the image
below.
That’s it. Once you click the Create Button, the project will be created with the Empty template
with the following folder and file structure.
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:
1. MVC Controller – Empty: It will create an Empty Controller.
2. MVC Controller with read/write actions: This template will create the
controller with five action methods to create, read, update, delete, and list
entities.
3. 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.
14
Once you click on 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 in it.
15
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
16
many more properties and methods, which we will use as part of our ASP.NET Core MVC
Application.
});
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 have a look at the following image to better understand how the above URL mapped
to the GetAllStudents action method of the Student controller.
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
need to 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 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 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.
Creating Controller Instance 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 in .NET 6 Application.
Then, we need to configure the MVC Middleware into the Request Processing Pipeline using
either conventional or attribute routing. For example, the following code will add the MVC
Middleware Component to the Application Processing Pipeline.
20
So, in the ASP.NET Core MVC Web Application, when the client sends an HTTP Request,
the MVC Middleware Component receives it. Once the MVC Middleware Component
receives the request, based on conventional or attribute 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.
As you can see, this class provides implementations for the IControllerActivator interface
methods. Further, the ASP.NET Core Framework uses
the DefaultControllerActivator constructor, which takes
the ITypeActivatorCache instance to create the controller. This is how the controller
instance is created in the ASP.NET Core MVC Application.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:11 / 03:1110 Sec
When you create a new ASP.NET Core Web Application using the Model-View-Controller
Template, all the model classes are created inside the Models folder by default. We are also
going to follow this naming convention. Let us see how to create and work with models in an
ASP.NET Core MVC Application.
Adding Models Folder in ASP.NET Core Application:
22
Right-click on your project, then select add => new folder option from the context menu to
add a new folder. Then, rename the folder name as Models. Here, we want to create a model
for displaying student data. So, create a class file named Student.cs within
the Models folder. Once you create the Student model, then the folder structure of your
application should look as shown below.
Now open the Student.cs class file and then copy and paste the following code. As you can
see, this is a very simple class having only 5 properties to hold the students’ information.
namespace FirstCoreMVCWebApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
This is our student model, which will store the student data in memory. As we already
discussed, the ASP.NET Core MVC Application model also contains business logic to
manage the data. So, in our example, to manage the student data, i.e., to perform the CRUD
operation on the student data, we will use the following IStudentRepository interface.
Creating IStudentRepository interface:
Right-click on the Models folder and add an interface named IStudentRepository.cs. Once
you create the interface, copy and paste the following code.
namespace FirstCoreMVCWebApplication.Models
23
{
public interface IStudentRepository
{
Student GetStudentById(int StudentId);
}
}
As you can see, we created the above interface with one method, the GetStudentById()
method, which retrieves the student details by the student ID.
Creating StudentRepository class:
Let us create an implementation class for the above IStudentRepository interface. In our
upcoming article, we will discuss retrieving student details from a database. But for this demo,
let’s hardcode the student details. So, create a class file with the
name StudentRepository.cs within the Models folder and then copy and paste the following
code into it.
using System.Collections.Generic;
using System.Linq;
namespace FirstCoreMVCWebApplication.Models
{
public class StudentRepository : IStudentRepository
{
public List<Student> DataSource()
{
return new List<Student>()
{
new Student() { StudentId = 101, Name = "James", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 102, Name = "Smith", Branch = "ETC", Section = "B",
Gender = "Male" },
new Student() { StudentId = 103, Name = "David", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 104, Name = "Sara", Branch = "CSE", Section = "A", Gender
= "Female" },
new Student() { StudentId = 105, Name = "Pam", Branch = "ETC", Section = "B", Gender
= "Female" }
};
24
}
public Student GetStudentById(int StudentId)
{
return DataSource().FirstOrDefault(e => e.StudentId == StudentId) ?? new Student();
}
}
}
Modify StudentController:
We already created a Controller named StudentController within the Controllers Folders. If
you have not created it, add a class file with the StudentController within the Controllers
folder. Then, modify the StudentController as shown below to use the StudentRepository to
retrieve the student details. The Student and StudentRepository are in a separate
namespace, so you must also include the namespaces.
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class StudentController : Controller
{
public JsonResult GetStudentDetails(int Id)
{
StudentRepository repository = new StudentRepository();
Student studentDetails = repository.GetStudentById(Id);
return Json(studentDetails);
}
}
}
If you are directly coming to this article without reading our previous article, please modify the
Main method of the Program class as shown below. This registers the MVC Services and
Middlewares to the application request processing pipeline.
namespace FirstCoreMVCWebApplication
{
public class Program
{
public static void Main(string[] args)
25
{
var builder = WebApplication.CreateBuilder(args);
// Add MVC services to the container.
builder.Services.AddMvc();
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
//Configuring the MVC middleware to the request processing pipeline
endpoints.MapDefaultControllerRoute();
});
app.Run();
}
}
}
Now run the application and navigate to https://localhost:<Port
Numbet>/Student/GetStudentDetails/102 URL, and you will see the student data in JSON
format, as expected in the browser, as shown in the image below.
As you can see in the above image, a separate folder is created for each controller within the
Views Folder. The Home folder represents the HomeController and the Student folder inside
the Views folder represents the Student Controller.
• The Home folder contains the views for the Index, AboutUs, and ContactUs
webpages. Whenever a user requests one of these web pages, the Home
Controller action method determines which of the above three views to use to
build the webpage and return it to the user.
• Similarly, the Student folder contains the Index, Details, Edit, and Delete web
page views. So, whenever a user requests any of these web pages, the
Student Controller action method determines which of the above views to use
to build the webpage and return to the user.
27
Note: In addition to action-specific views, we have also provided partial views, layouts, and
view components that can reduce repetition and allow for reuse within the application’s views.
We will discuss each of these in our upcoming articles.
Example to Understand Views in ASP.NET Core MVC Application:
We will work with the same example we created in our ASP.NET Core Controllers article
and continue in Models in the ASP.NET Core article.
Adding Home Controller
We have already created one controller called Student Controller within the Controllers folder.
Let us add a new Controller named HomeController within the Controllers folder. At this
time, your project folder structure should look like the one below.
Open HomeController and then copy and paste the following code into it.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
}
}
As you can see in the above HomeController class, we have only one action method, Index.
The return type of the Index() action method is ViewResult, which means it will return a view.
To return a view, we use the View() extension method, which belongs to the Controller Base
Class.
28
Note: Views are typically returned from the Action method as a ViewResult, which is a type
of ActionResult. Your action method can create and return a ViewResult directly, but that
isn’t commonly done. Since most ASP.NET Core MVC Controllers are inherited from the
Controller base class, we can use the View helper method to return the ViewResult.
Now run the application and navigate to the “/Home/Index” URL or the default URL, and you
will see the following error.
Once you click the Add button, it will open the Add Razor View window. Here, you need to
give the View name as Index, select the Empty (without model) template, uncheck the
creation of a partial view, use a layout page checkbox, and then click on the Add button as
shown below.
Once you click the Add button, the Index.cshtml view should be created within the Home
folder, as shown in the image below.
30
Now open Index.cshtml file and then copy and paste the following code into it.
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<h1>Index view belongs to Views/Home folder</h1>
</body>
</html>
With the above changes in place, run the application, and you should get the expected output,
as shown in the image below.
31
Let us understand the use and significance of each of the above-overloaded versions of the
View Extension method.
View() vs View(object model) Extension Methods:
If you use the View() or View(object model) extension method to return a view, it will look for
the view file with the same name as the action method name. If you want to pass model data,
you need to use the overloaded version of the View method, which takes the object model as
an input parameter; otherwise, you can use the View() extension method, which does not
take any parameter.
For example, in the code below, we are using the View() extension method, which does not
take any parameter to return a view from the Index action method of the Home Controller.
So, in this case, by default, the ASP.NET Core MVC framework will look for a view with the
name Index.cshtml within the “Views/Home” folder.
Once you created the Test.cshtml view, then open the Test.cshtml file and copy-paste the
below code in it.
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Test</title>
</head>
<body>
<h1>Test view coming from Views/Home Folder</h1>
</body>
</html>
Now, modify the Index action method of the HomeController class as shown below to use the
View extension method, which takes the view name as a parameter.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View("Test");
}
}
}
Now run the application and navigate to the “/Home/Index” URL. As shown in the image
below, the response is coming from the Test view.
33
Relative Path
• A relative path is relative to the location of the calling controller. In ASP.NET
Core, the default convention is to look for views in a folder that matches the
controller name within the Views folder.
• Example: If you have a HomeController, calling return View(“Index”); will by
default look for the view in Views/Home/Index.cshtml.
When to Use:
• Use relative paths when the views are located in the conventional locations
(e.g., Views/[ControllerName]/[ViewName].cshtml).
• Use absolute paths when you need to reference a view outside of the
conventional locations or when you want to ensure the path remains valid
regardless of controller location.
Another way of Creating Views:
Let us add a new action to the HomeController with the name About. So, please modify the
HomeController as shown below.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
public ViewResult About()
{
return View();
}
}
}
Now, right-click anywhere within the About action method and click on the Add View from the
context menu, as shown in the image below.
35
Once you click on the Add View, it will open the Add New Scaffolded Item window, as shown
below. In this window, you need to select the Razor View and click on the Add button, as
shown in the image below.
36
Once you click on the Add button, the Add Razor View window will open. By default, the View
will be named About (action method name). Finally, click the Add button, as shown in the
image below.
Once you click the Add button, it will add the About.cshtml file within the View/Home folder,
as shown in the below image.
Once you click on the Create a new project tab, it will open the Create a new project window.
You need to select the ASP.NET Core Empty project template from this window and click the
Next button, as shown in the image below.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:17 / 03:1110 Sec
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
38
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, the Additional Information window will open. You must
select .NET 6.0 as the Framework, check the Configure for HTTPS and do not use top-level
statements check boxes, and finally click on the Create button, as shown in the image below.
That’s it. Once you click the Create Button, the project will be created with the Empty template
with the following folder and file structure.
39
Adding Models:
Once you created the ASP.NET Core Empty Project, let’s add our models. To do so, first,
create a folder with the name Models. Within the Models folder, let us add a class file with
the name Student.cs, and this Student class will be our model for this application. Then open
the Student.cs class file and copy and paste the following code into it.
namespace FirstCoreMVCWebApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
Creating Service Interface:
Next, create an interface named IStudentRepository.cs within the Models folder. This
interface will declare the list of methods or operations we can perform on the student data.
So, open IStudentRepository.cs and copy and paste the following code. Here, you can see
we have created the interface with two methods.
using System.Collections.Generic;
namespace FirstCoreMVCWebApplication.Models
{
public interface IStudentRepository
{
Student GetStudentById(int StudentId);
List<Student> GetAllStudent();
}
}
Creating Service Implementation:
Next, create a class file named StudentRepository.cs within the same Models folder. Then
open the StudentRepository.cs class file and copy-paste the following code. This class
implements the IStudentRepository interface by implementing the two methods declared in
the IStudentRepository interface. Here, we have hard-coded the student data, but you will get
the student data from a database in real-time applications.
using System.Collections.Generic;
40
using System.Linq;
namespace FirstCoreMVCWebApplication.Models
{
public class StudentRepository : IStudentRepository
{
public List<Student> DataSource()
{
return new List<Student>()
{
new Student() { StudentId = 101, Name = "James", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 102, Name = "Smith", Branch = "ETC", Section = "B",
Gender = "Male" },
new Student() { StudentId = 103, Name = "David", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 104, Name = "Sara", Branch = "CSE", Section = "A", Gender
= "Female" },
new Student() { StudentId = 105, Name = "Pam", Branch = "ETC", Section = "B", Gender
= "Female" }
};
}
public Student GetStudentById(int StudentId)
{
return DataSource().FirstOrDefault(e => e.StudentId == StudentId) ?? new Student();
}
public List<Student> GetAllStudent()
{
return DataSource();
}
}
}
Program.cs:
41
In the Program class, we need to do two things. First, we need to configure the required MVC
service to the IoC Container, and then we need to add the MVC Middleware to the request
processing pipeline. So, modify the Program class as shown below.
namespace FirstCoreMVCWebApplication
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add MVC services to the container.
builder.Services.AddMvc();
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
//Configuring the MVC middleware to the request processing pipeline
endpoints.MapDefaultControllerRoute();
});
app.Run();
}
}
}
Without Dependency Injection:
Create a folder named Controllers in your project. Then, add a class file
named HomeController.cs within the Controllers folder. Then open the HomeController.cs
file and copy-paste the following code into it. Here, you can see that within the Index and
GetStudentDetails action methods, we are creating an instance of the StudentRepository
class and calling the respective methods.
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
42
Let us first understand the problem in the above implementation. Then, we will discuss how
we can overcome it by using the Dependency Injection Design Pattern in the ASP.NET Core
application.
What is the Problem with the above implementation?
43
As you can see in the above HomeController class, the HomeController class depends on an
instance of the StudentRepository class to get student data. Here, within the HomeController
class, we create an instance of the StudentRepository class and then invoke
the GetStudentById() and GetAllStudent methods as per our requirement. This is tight
coupling because the HomeController class is now tightly coupled with the StudentRepository
concrete class.
Tomorrow, if the implementation class of the IStudentRepository is changed
from StudentRepository to TestStudentRepository, then we also need to make the
changes to the code in the HomeController class, as they are both tightly coupled. We can
overcome this problem by implementing the Dependency Injection Design Pattern.
What is the Dependency Injection (DI) Design Pattern?
Dependency Injection is the process of injecting the dependency object into a class that
depends on it. It is the most commonly used design pattern nowadays to remove the
dependencies between objects, allowing us to develop loosely coupled software
components. Let us discuss the step-by-step procedure of how to implement dependency
injection in the ASP.NET Core MVC application.
The ASP.NET Core Framework is designed from scratch to provide inbuilt support for
Dependency Injection Design Patterns. The ASP.NET Core Framework injects the
dependency objects to a class through a constructor or method using the built-in IoC
(Inversion of Control) container.
The built-in IoC (Inversion of Control) container is represented
by IServiceProvider implementation, which supports default constructor injection. The types
(i.e., classes) managed by built-in IoC containers are called services.
Types of Services in ASP.NET Core:
There are two types of services in ASP.NET Core. They are as follows:
1. Framework Services: Services that are a part of the ASP.NET Core
Framework, such as IApplicationBuilder, IHostingEnvironment,
ILoggerFactory, etc.
2. Application Services: The services (custom types or classes) you create as
a programmer for your application.
To let the IoC container automatically inject our application services, we must first register
them with the IoC container.
How do you Register a Service with ASP.NET Core Dependency Injection
Container?
We need to register a service with the ASP.NET Core Dependency Injection Container within
the Main method of the Program class. Before we discuss how to Register a service with the
Dependency Injection Container, it is important to understand the service’s lifetime. Setting
the lifetime of the dependency object determines how many times it needs to be created.
What are the Different Methods ASP.NET Core Provides to Register a
Service with the Dependency Injection Container?
ASP.NET Core provides 3 methods for registering a service with the ASP.NET Core
Dependency Injection container. The method we use to register a service will determine its
lifetime.
Singleton:
A Singleton service is created only once per application lifetime. The same instance is used
throughout the application. It is ideal for stateless services or maintaining a consistent state
throughout the application’s lifetime. Common uses include configuration services, logging,
44
or other services where a single instance is sufficient and desirable. This can be achieved by
adding the service as a singleton through the AddSingleton method of the IServiceCollection.
Transient:
A Transient service is created each time it is requested from the service container. This
means a new instance is provided to every class or method that requires it. This is ideal for
lightweight, stateless services. Since a new instance is always created, you don’t need to
worry about thread safety related to the internal state. This can be achieved by adding the
service through the AddTransient method of the IServiceCollection.
Scoped:
A Scoped service is created once per client request (in a web application, this typically means
per HTTP request). This is ideal for services that need to maintain state within a single
request but should not be shared across different requests. Common examples include data
access operations within a single transaction. This can be achieved by adding the service
through the AddScoped method of the IServiceCollection.
Registering the StudentRepository with ASP.NET Core Dependency
Injection
We need to register the service to the built-in dependency injection container with the program
class. The following code shows how to register a service with different lifetimes:
Let us use the service’s Singleton Instance in this example. Modify the Main method of the
Program class as shown below. Which approach do you want to use to register the service?
It is your preference.
using FirstCoreMVCWebApplication.Models;
namespace FirstCoreMVCWebApplication
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add Framework MVC services to the Container.
builder.Services.AddMvc();
//Application Service
builder.Services.AddSingleton<IStudentRepository, StudentRepository>();
//builder.Services.AddSingleton(typeof(IStudentRepository),
typeof(StudentRepository));
//builder.Services.AddTransient<IStudentRepository, StudentRepository>();
//builder.Services.AddTransient(typeof(IStudentRepository),
typeof(StudentRepository));
//builder.Services.AddScoped<IStudentRepository, StudentRepository>();
//builder.Services.AddScoped(typeof(IStudentRepository),
typeof(StudentRepository));
//Add Application Service to the Container.
//builder.Services.Add(new ServiceDescriptor(typeof(IStudentRepository),
46
{
_repository = repository;
}
public JsonResult Index()
{
List<Student>? allStudentDetails = _repository?.GetAllStudent();
return Json(allStudentDetails);
}
public JsonResult GetStudentDetails(int Id)
{
Student? studentDetails = _repository?.GetStudentById(Id);
return Json(studentDetails);
}
}
}
Code Explanation:
In the above example, the IoC container will automatically inject an instance of
the StudentRepository into the constructor of HomeController. We don’t need to do anything
else. An IoC container will create and dispose of an instance of the IStudentRepository based
on the registered lifetime. Injecting the dependency object through a constructor is called a
constructor dependency injection.
We created the _ repository variable as read-only, ensuring that once we inject the
dependency object, that value can never be changed. At this point, run the application, and
you should get the output as expected, as shown in the below image.
48
}
Run the application, and you will get the expected output, as shown below.
return Json(allStudentDetails);
}
public JsonResult GetStudentDetails(int Id)
{
var services = this.HttpContext.RequestServices;
IStudentRepository? _repository =
(IStudentRepository?)services.GetService(typeof(IStudentRepository));
Student? studentDetails = _repository?.GetStudentById(Id);
return Json(studentDetails);
}
}
}
With the above changes in place, run the application, and you should get the output as
expected as in the previous examples. It is recommended to use constructor injection instead
of getting it using RequestServices.
What is the GetService Method in ASP.NET Core?
The GetService method in ASP.NET Core is a part of the dependency injection (DI) system
provided by the framework. It is used to retrieve a service instance from the DI container. You
need to pass the type of service you want to retrieve as a parameter to this method.
What are the Advantages of using ASP.NET Core Dependency Injection?
The ASP.NET Core Dependency Injection allows us to develop loosely coupled software
components. Here are some of the advantages of using dependency injection in ASP.NET
Core:
1. Loose Coupling: By using dependency injection, we can separate our
classes from their dependencies, resulting in code that is simpler to maintain
and test.
2. Testability: By using dependency injection, we can increase the testability of
our code by easily replacing dependencies with mock objects during unit
testing.
3. Extensibility: Using Dependency injection enhances the extensibility of our
code by offering the flexibility to switch out dependencies conveniently.
4. Reusability: Using dependency injection makes our code more reusable
since we can conveniently share dependencies among various classes.
Creating ASP.NET Core Application using MVC
Template
In this article, I will discuss How to Create ASP.NET Core Web Applications using MVC
(Model-View-Controller) Project Template and understand the Folder and File
Structure. Please read our previous article before proceeding to this article, where we
discussed ASP.NET Core Dependency Injection with Examples.
Creating an ASP.NET Core MVC Application:
51
As of now, we have discussed everything using the ASP.NET Core Empty Project Template
and understand the different parts of an ASP.NET Core MVC Application. We also discussed
Setting up the MVC Request pipeline in the ASP.NET Core Web Application.
But the question is, do we need to manually set up everything to create an ASP.NET Core
MVC Application? The answer is NO. The ASP.NET Core Framework provides one built-in
Project Template called ASP.NET Core Web App (Model-View-Controller), which will create
an ASP.NET Core MVC Application for us with the required MVC setup. From now onwards,
in this ASP.NET Core MVC course, we will create the applications using the ASP.NET Core
Web App (Model-View-Controller) Project template.
Creating an ASP.NET Core Application using the MVC Project Template:
To create an ASP.NET Core Web Application with the MVC Project template. First, open
Visual Studio 2022 and click the Create a new project tab, as shown in the image below.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People Know
Once you click on the Create a new Project tab, the following Create a new Project window
will open. From this window, select C#, All Platforms, and Web from the respective
dropdowns, as highlighted below. Select “ASP.NET Core Web App (Model-View-Controller),”
as highlighted below, and click on the “Next” button, as shown in the image below.
52
Once you click on the Next button, it will open the Configure Your New Project window.
You must provide the necessary information to create a new ASP.NET Core project here.
First, give an appropriate name for your project (SampleMVCWeb), 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 the Create button, the following Additional Information window will open: You
must select Framework – .NET 6.0 (Long-term support), Authentication type – None.
You must also 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.
53
Once you click on the Create Button, the project will be created with the Web Application
(Model-View-Controller) template, i.e., the MVC template, with the following folder and file
structure.
54
wwwroot Folder:
The wwwroot folder is the root of the web server or project’s web root directory and contains
all the static files your application serves directly to clients, such as HTML, CSS, JavaScript,
and image files. Files in this folder are accessible via a URL, unlike other parts of your
application. It is the default static file location, but you can configure ASP.NET Core to use
different or additional directories.
Controllers Folder:
The Controllers folder contains classes that handle client requests and return a response.
Each controller class is typically responsible for a specific area of the application. Controllers
process incoming requests, perform operations on the data through the models, and select a
view to render a response. The methods inside controller classes are called actions and
mapped to different routes defined in the application.
Models Folder:
The Models folder contains classes representing the application’s data and the logic to
manage that data. Models transfer data between the controllers and the views or represent
the data that needs to be persisted in a database. They often correspond to database tables
in applications that use Entity Framework Core. For instance, a Product model might
represent a product table in a database.
Views Folder:
The Views folder contains files that are used to generate the HTML content returned to the
client. These files are typically Razor view files (.cshtml), which mix HTML markup with C#
code for dynamic content generation. Views are organized into subfolders, usually with a
folder for each controller, and the view files correspond to actions in the controller.
Shared Folder:
The Shared folder in ASP.NET Core MVC stores shared resources like Razor layout pages
(_Layout.cshtml), partial views, or other common components used across different views in
your application. It helps maintain a consistent look and feel across your site and promotes
the reusability of views and components. The Shared folder is typically located under the
Views directory.
_ViewStart.cshtml File:
The _ViewStart.cshtml file defines common settings applied to all Razor views in the
application (or in a specific folder if multiple _ViewStart.cshtml files are used). It’s executed
before the rendering of each view. This makes it ideal for setting layout pages and other
common settings.
ViewImports.cshtml File:
The _ViewImports.cshtml file includes common Razor directives that you want to be available
in your views. It helps in reducing code duplication. Common uses of _ViewImports.cshtml
include:
• Importing namespaces so you don’t have to add @using directives to every
view.
• Adding Tag Helpers, a feature in ASP.NET Core that enables server-side
code to create and render HTML elements in Razor files.
appsettings.json file
• The appsettings.json file is used for configuration purposes. It stores
configuration data in a JSON format, including database connection strings,
application settings, logging configuration, and more.
56
builder.Services.AddControllersWithViews();
if (!app.Environment.IsDevelopment())
app.UseExceptionHandler("/Home/Error");
57
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
}
Running the MVC Application:
The ASP.NET Core Web APP (Model-View-Controller) Project template creates the Home
Controller with some views. Let’s run the application and see the output, as shown below.
58
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:16 / 03:1110 Sec
As you can see in the above image, the data type of ViewData Property is
ViewDataDictionary. Let’s have a look at the definition of the ViewDataDictionary by right-
clicking on it and selecting go to definition, and you will see the following definition.
59
As you can see in the above image, the ViewDataDictionary class implements the IDictionary.
So, ViewData in ASP.NET Core MVC is a dictionary object. As it is a dictionary object, it will
store the data in the form of Key-Value Pairs where each key must be a string, and the value
that we pass to the dictionary will be stored as an object type. Here, the key is of type String,
and the value is of type object, i.e., we can store any data, including null.
How do you use ViewData in the ASP.NET Core MVC Application?
To use ViewData in the ASP.NET Core MVC Application, we first need to create a new key
in ViewData and then assign some data to it. The key should be in string format, and you can
give any name to the key. Then, you can assign any data to this key, such as the following.
ViewData[“KeyName”] = “Some Data”;
Since ViewData is a server-side code, hence to use it on a view, we need to use the razor
syntax, i.e., @ something as follows.
@ViewData[“KeyName”]
You can access the string data from the ViewData dictionary without casting the data to string
type. But if you are accessing data other than the string type, you must explicitly cast the data
to the type you expect.
How to Access String Data using ViewData in ASP.NET Core MVC
Let us see an example of using ViewData to pass data from a controller action method to a
view. In our example, we want to pass three pieces of information from the controller action
method to the view. One is the Page’s title, the second is the page’s Header, and the third is
the Student data.
So, first, create an ASP.NET Core Web Application (with the
name FirstCoreMVCWebApplication) with MVC (Model-View-Controller) Project Template,
i.e., Creating ASP.NET Core Application using ASP.NET Core Web APP (Model-View-
Controller) Template. Once you create the project, add a class file named Student.cs in the
Models folder. Then, please copy and paste the code below into it.
namespace FirstCoreMVCWebApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
Modifying HomeController:
Next, modify the Home Controller class as shown below. Here, we remove the existing code
and add one action method, i.e., Details. As part of this method, we create three ViewData
objects to store the Title, Header, and Student data. Here, Title, Header, and Student are the
keys of the ViewData Dictionary Object.
using Microsoft.AspNetCore.Mvc;
using FirstCoreMVCWebApplication.Models;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Details()
{
//String string Data
ViewData["Title"] = "Student Details Page";
ViewData["Header"] = "Student Details";
Student student = new Student()
61
{
StudentId = 101,
Name = "James",
Branch = "CSE",
Section = "A",
Gender = "Male"
};
//storing Student Data
ViewData["Student"] = student;
return View();
}
}
}
Creating Details.cshtml View:
Our previous article discussed the different ways to create Views in ASP.NET Core MVC
Applications. Let us add a view with the name Details.cshtml within the Home folder, which
is present inside the Views folder, as shown below. Once you add the Details view, your
Views folder structure should look as shown below.
Now open the Details.cshtml view and copy and paste the following code into it. As you can
see in the code below, we directly access the string data from the ViewData without type
casting. However, while accessing the Student data from the ViewData, we typecast it to the
appropriate Student type.
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewData["Title"]</title>
</head>
<body>
62
<h1>@ViewData["Header"]</h1>
@{
var student = ViewData["Student"] as FirstCoreMVCWebApplication.Models.Student;
}
<div>
StudentId : @student?.StudentId
</div>
<div>
Name : @student?.Name
</div>
<div>
Branch : @student?.Branch
</div>
<div>
Section : @student?.Section
</div>
<div>
Gender : @student?.Gender
</div>
</body>
</html>
Now run the application and navigate to the “/Home/Details” URL. As shown below, you will
see the data as expected.
63
Features of ViewData
• Type Safety: ViewData does not provide type safety as it stores data as
object. You need to cast the data to the appropriate type when retrieving it.
• Scope: The data in ViewData only lasts for the duration of the current HTTP
request. It’s reset for each new request, so it is not a mechanism for persisting
data between requests, such as across redirects.
• Accessing Data: You can set data in a controller by adding entries to the
ViewData dictionary with a string key. In the view, you can access these values
using the same key. When used in the view, the values must be cast to the
appropriate type.
• Null Handling: Since ViewData returns null if a key does not exist, you
should check for null or use the ?. operator to avoid exceptions.
• Usage: ViewData is best used to pass small amounts of data. If you’re
passing complex data or require type safety, consider using ViewBag or
strongly typed views.
properties to the ViewBag object in the controller actions, which are then accessible in the
Razor views. If you go to the Controller abstract class, you will find the following signature of
the ViewBag property.
How Do We Pass and Retrieve Data from ViewBag in ASP.NET Core MVC?
You need to keep in mind that ViewBag operates on a dynamic data type. So, we don’t require
typecasting while accessing data from a ViewBag. It does not matter whether the data we are
accessing is of type string or any complex type.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:04 / 03:1110 Sec
How to Access Data from ViewBag in ASP.NET Core MVC with String Type:
How to Access Data from ViewBag in ASP.NET Core MVC with Complex Type:
65
Note: Dynamic Data Types means the data type will be decided at runtime based on the
right-hand side values. So, we don’t require typecasting if we use ViewBag.
Example to Understand ViewBag in ASP.NET Core MVC Application:
Let us see an example of using ViewBag to pass data from a controller action method to a
view in the MVC Application. We will work with the example we worked on in our previous
article with ViewData. So, modify the Details action method of the HomeController class as
shown below.
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Details()
{
ViewBag.Title = "Student Details Page";
ViewBag.Header = "Student Details";
Student student = new Student()
{
StudentId = 101,
Name = "James",
Branch = "CSE",
Section = "A",
Gender = "Male"
};
ViewBag.Student = student;
66
return View();
}
}
}
As you can see in the above example, here we are using the dynamic properties Title, Header,
and Student on the ViewBag.
Accessing ViewBag in a View in ASP.NET Core
Now, we will see how to access the ViewBag data within a View in MVC Application. So,
modify the Details.cshtml view file as shown below. Here, you can see we are directly
accessing the string and complex type values without typecasting, and this is possible
because of the dynamic data type.
@{
Layout = null;
var student = ViewBag.Student;
}
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
<h1>@ViewBag.Header</h1>
<div>
StudentId : @student?.StudentId
</div>
<div>
Name : @student?.Name
</div>
<div>
Branch : @student?.Branch
</div>
<div>
Section : @student?.Section
</div>
<div>
67
Gender : @student?.Gender
</div>
</body>
</html>
As you can see, we are accessing the data from the ViewBag using the same dynamic
properties: Title, Header, and Student. Now run the application and navigate to the
“/Home/Details” URL, and you will see the data as expected on the webpage, as shown in
the image below.
Features of ViewBag
• Weakly Typed: Since ViewBag is dynamic, it doesn’t offer compile-time type
checking. This can lead to runtime errors if you attempt to use properties that
do not exist or if there is a type mismatch. This flexibility allows for easy-to-
write code but requires careful handling to avoid errors.
• Usage: Like ViewData, ViewBag passes data from a controller to a view. It’s
useful for transferring lightweight and non-complex data. For instance, you
might use ViewBag to pass page titles, display messages, or manage simple
settings that do not require a structured format.
• Scope: The scope of ViewBag is limited to the current HTTP request, just like
ViewData. It is not suitable for passing data across multiple requests, as it gets
cleared at the end of each request.
• No Explicit Casting Required: Unlike ViewData, when you access
properties on ViewBag, you do not need to cast them since they are dynamic.
However, this also means less safety against type mismatches.
68
• Null Handling: Accessing a property that hasn’t been set will return null, so
do not throw an exception because ViewBag uses the dynamic feature.
Strongly Typed View in ASP.NET Core MVC Application
In this article, I will discuss How to Create a Strongly Typed View in ASP.NET Core
MVC Application with Examples. Please read our previous article discussing ViewBag in
ASP.NET Core MVC Application. As part of this article, we will discuss the following pointers.
1. Why do we need a Strongly Typed View in ASP.NET Core MVC?
2. How do you create a Strongly Typed View in ASP.NET Core MVC?
3. What are the Advantages of using a Strongly Typed View?
4. When should you use a Strongly Typed View in ASP.NET Core MVC?
Why do we need a Strongly Typed View in ASP.NET Core MVC?
As we already discussed, in ASP.NET Core MVC, we can pass the model data to a view
using many different methods, such as ViewBag, ViewData, TempData, Strongly Typed View
Model, etc. The view becomes loosely typed when we pass the model data to a View using
ViewBag, TempData, or ViewData. We will not get intelligence support or compile-time error
checking in a loosely typed view.
A strongly typed view in ASP.NET Core MVC is a view specifically designed to work with a
particular type of model. This model is passed from the controller to the view, allowing for
direct interaction with the data structure. The compiler provides Type-Checking and
IntelliSense support for the data being used in the view. Strongly typed views enhance code
quality, reduce runtime errors, and improve maintainability by ensuring that the data used in
the view aligns with the expected data structure.
How Do We Create Strongly Typed Views in ASP.NET Core MVC?
To create a strongly typed view in ASP.NET Core MVC, we need to follow the below steps:
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
1. Create a Model: Define a model class representing the data you want to
display in the view. This class contains properties corresponding to the data
you need to access and render in the view.
2. Pass the Model to the View: In the controller action, create an instance of
the model class, populate it with data, and then pass it to the view.
3. Declare the Model in the View: At the top of the view file, declare the model
type using the @model directive. This informs the view about the type of data
it will be working with.
4. Access Model Properties in the View: Inside the view, you can access the
properties of the model using Razor syntax (@Model.PropertyName). The
compiler provides IntelliSense support for the properties of the model, helping
you avoid typos and access properties safely.
Example to Understand Strongly Typed View in ASP.NET Core MVC
Application
Create a Model
First, you need to define a model class. A model is a C# class with properties. This class will
be used to transfer data between your controller and view. We will use the same application
we used in our previous two articles. So, we are going to use the same Student model. If you
69
are coming to this article directly without reading our previous two articles, then please create
the following Student class within the Models folder:
namespace FirstCoreMVCWebApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
To create a Strongly Typed View from the controller’s action method, we must pass the model
object as a parameter to the View() extension method. The Controller base class provides
the following two overloaded versions of the View() extension method, which we can use to
pass the model object from the controller action method to a view in the ASP.NET Core MVC
Application.
We will use the example we worked on in our previous two articles. Now, we will use the
overloaded version of the Views() Extension method, which takes only the model object as
an input parameter. So, modify the Details action method of the Home Controller, as shown
below, to pass the student object as a parameter to the View extension method.
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Details()
{
//Using ViewBag
ViewBag.Title = "Student Details Page";
//Using ViewData
70
<title>@ViewBag.Title</title>
</head>
<body>
<h1>@ViewData["Header"]</h1>
<div>
StudentId : @Model?.StudentId
</div>
<div>
Name : @Model?.Name
</div>
<div>
Branch : @Model?.Branch
</div>
<div>
Section : @Model?.Section
</div>
<div>
Gender : @Model?.Gender
</div>
</body>
</html>
Now run the application and navigate to the /Home/Details URL. As shown in the image
below, you will see the data as expected.
72
In Real-Time Applications, a single model object may not contain all the data required for a
view. We must use a View Model in the ASP.NET Core MVC application in such situations.
In simple words, a View Model in ASP.NET Core MVC is a model that contains more than
one model data required for a particular view.
In ASP.NET Core MVC, a View Model is a Design Pattern used to create a model specifically
designed for a view. It shapes the data in a way that is most convenient for rendering in a
view, which may involve aggregating, transforming, or simplifying data from one or more data
models or sources.
Understanding the ViewModel in ASP.NET Core MVC:
The following diagram shows the visual representation of a view model in the ASP.NET Core
MVC application.
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:23 / 03:1110 Sec
Let’s say we want to display the student details in a view. We have two different models to
represent the student data. The Student Model is used to represent the student’s basic
details, whereas the Address model is used to represent the student’s address. Along with
the above two models, we also required some static information in the view, like the page
header and page title. If this is our requirement, then we need to create a view model, say
StudentDetailsViewModel, and that view model will contain both the models (Student and
Address) and properties to store the page title and page header.
Creating the Required Models:
We will use the same example from our previous article. First, modify the Student.cs class
file, which is present within the Models folder of your application, as follows. This model will
represent a student’s basic information, such as a Name, Branch, Section, etc.
namespace FirstCoreMVCWebApplication.Models
{
74
//Student Address
Address address = new Address()
{
StudentId = 101,
City = "Mumbai",
State = "Maharashtra",
Country = "India",
Pin = "400097"
};
//Creating the View model
StudentDetailsViewModel studentDetailsViewModel = new StudentDetailsViewModel()
{
Student = student,
Address = address,
Title = "Student Details Page",
Header = "Student Details",
};
//Pass the studentDetailsViewModel to the view
return View(studentDetailsViewModel);
}
}
}
As you can see, we are now passing the view model as a parameter to the view. This view
model contains all the data required by the Details view. We are not using any ViewData or
ViewBag to pass the Page Title and Header to the view; instead, they are also part of the
ViewModel, which makes it a strongly typed view.
Creating the Details View:
First, add a folder with the name Student within the Views folder of your project. Once you
add the Student Folder, then you need to add a Razor view file with the
name Details.cshtml within the Student folder. Once you add the Details.cshtml view, then
copy and paste the following code into it.
@model FirstCoreMVCWebApplication.ViewModels.StudentDetailsViewModel
@{
Layout = null;
}
<html xmlns="http://www.w3.org/1999/xhtml">
77
<head>
<title>@Model?.Title</title>
</head>
<body>
<h1>@Model?.Header</h1>
<div>
StudentId : @Model?.Student?.StudentId
</div>
<div>
Name : @Model?.Student?.Name
</div>
<div>
Branch : @Model?.Student?.Branch
</div>
<div>
Section : @Model?.Student?.Section
</div>
<div>
Gender : @Model?.Student?.Gender
</div>
<h1>Student Address</h1>
<div>
City : @Model?.Address?.City
</div>
<div>
State : @Model?.Address?.State
</div>
<div>
Country : @Model?.Address?.Country
</div>
<div>
Pin : @Model?.Address?.Pin
</div>
78
</body>
</html>
Now, the Details view has access to the StudentDetailsViewModel object that we passed
from the controller action method using the View() Extension method. Using
the @model directive, we set StudentDetailsViewModel as the Model for the Details view.
Then, we access Student, Address, Title, and Header using the @Model property.
Now run the application and navigate to the /Student/Details URL. As shown in the image
below, you will see the expected output on the webpage.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:17 / 03:1110 Sec
As you can see in the above image, the data type of the TempData is ITempDataDictionary.
Let us see the definition of the ITempDataDictionary class.
As you can see, the ITempDataDictionary class implements the IDictionary interface. So, we
can say that TempData in ASP.NET Core MVC is a dictionary object. As a dictionary object,
it stores data in the form of key-value pairs, where each key must be a string. The value we
pass to the dictionary will be stored as an object type. Here, you can also see that to manage
the TempData value in ASP.NET Core MVC, it provides 5 methods. The use of these
methods is as follows:
Load:
The framework uses the Load method internally to load TempData from the underlying
TempData provider when an HTTP request begins. You typically won’t need to use this
method directly in your applications. It’s more of a system-level function that ensures
TempData is available for your actions during an HTTP request.
Save:
Similar to Load, the Save method is also used internally by ASP.NET Core. It saves the
current state of TempData back to the underlying TempData provider at the end of an HTTP
request. This method maintains TempData across redirects because it ensures that any
changes you’ve made during the request are persisted correctly.
Keep:
The Keep method marks all items in TempData to be retained for the next request. This
method is useful when you want to ensure that TempData is not removed at the end of the
current request, allowing it to be available for another subsequent request.
Keep(string key):
81
This overloaded version of the Keep method works like the general Keep method but allows
you to specify a single key to retain in TempData. Only the TempData entry with this specified
key will be preserved for the next request, while others will be discarded (unless they, too,
are explicitly kept). This method is useful when you need to retain specific information.
Peek(string key)
The Peek method retrieves the value associated with the specified key without marking it for
deletion when TempData is read. This is useful when you need to read a TempData value to
display on a page but also need it to persist for another subsequent request. Unlike reading
TempData using the String Indexer, which marks the item for deletion, Peek allows the data
to be read and still remain in TempData for further requests.
How do you Pass and Retrieve data from TempData in ASP.NET Core
MVC?
The most important point you need to remember is that it stores the data as an object, so
while retrieving the data from TempData, type casting is required. If you are accessing string
values from TempData, typecast is not required. However, it is mandatory to typecast
explicitly to the actual type if you are accessing data other than the string type from the
TempData.
Example to Understand TempData in ASP.NET Core MVC Application
We will use the same application we worked on in our previous article. Modify the
HomeController to use TempData, as shown below. As you can see, we have created three
action methods here. In the Index action method, we have set the Name and Age values
using TempData, and in the other two action methods, we are not doing anything.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["Name"] = "Pranaya";
TempData["Age"] = 30;
return View();
}
public ActionResult Privacy()
{
return View();
}
public ActionResult About()
{
return View();
82
}
}
}
Next, modify the Index, Privacy and add the About Views within the Home Folder, which is
inside the Views folder as follows:
Index.cshtml
@{
ViewData["Title"] = "Index Page";
}
<div class="text-left">
<b>Name:</b> @TempData["Name"]
<br />
<b>Age:</b> @TempData["Age"]
</div>
Privacy.cshtml
@{
ViewData["Title"] = "Privacy Policy";
}
<div class="text-left">
<b>Name:</b> @TempData["Name"]
<br />
<b>Age:</b> @TempData["Age"]
</div>
About.cshtml
@{
ViewData["Title"] = "About Page";
}
<div class="text-left">
<b>Name:</b> @TempData["Name"]
<br />
<b>Age:</b> @TempData["Age"]
</div>
The implementation of all three methods is the same. From each view, we access the
TempData values using the String Indexer, i.e., using the string key name. Now, run the
83
application and visit the Index Page, and you will get the data as expected, as shown in the
image below.
Now, if you visit Privacy and About, you will not get the data as expected, as shown in the
image below.
84
Why are we not getting the TempData value in the next subsequent
Request?
The reason is that once we read the value from TempData using the String Indexer, it will
mark the item for deletion from the TempData dictionary collection. And this is the default
behavior of TempData. In our example, we are reading the TempData within the Index View.
Hence, after reading the Age and Name keys from TempData, these two keys will be deleted
from the TempData dictionary collection.
How Do We Retain the TempData value in the next Sub Sequent Request
in ASP.NET Core MVC?
We can retain the TempData values for the next subsequent request in many ways. Let us
discuss them one by one.
Method 1: Don’t Fetch the Data from TempData
Suppose we don’t fetch the data from the TempData either from the Index Action Method or
the Index View. In that case, the TempData will be preserved in the TempData dictionary
collection and can be accessed from the next subsequent request. To do so, let us modify
the Index.cshtml view as follows. As you can see, we are only fetching the Age key from
85
TempData, not the Name key, which means the Name key will be preserved in the TempData
dictionary collection for the next request.
@{
ViewData["Title"] = "Index Page";
}
<div class="text-left">
<b>Name:</b>
<br />
<b>Age:</b> @TempData["Age"]
</div>
Now, run the application, visit the Index page, and then visit either the Privacy or About Page,
as shown in the image below. You can see that the age value is on the index page, and the
name value is on the privacy page.
Now, if you visit the About page, you will not see the data shown in the image below.
The Keep() method will Mark all keys in the dictionary for retention. On the other hand,
the Keep(string key) method marks the specified key in the dictionary for retention.
To better understand, please modify the Home Controller as follows. Here, you can see inside
the Index Action method we call the Keep method.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["Name"] = "Pranaya";
TempData["Age"] = 30;
//Retention of All keys of TempData for the next request
//TempData.Keep();
//Retention of Individual keys of TempData for the next request
TempData.Keep("Name");
TempData.Keep("Age");
return View();
}
public ActionResult Privacy()
{
return View();
}
public ActionResult About()
{
return View();
}
}
}
Next, modify the Index.cshtml view as follows. As you can see, we are fetching both keys
from the TempData Dictionary Collection.
@{
ViewData["Title"] = "Index Page";
}
87
<div class="text-left">
<b>Name:</b> @TempData["Name"]
<br />
<b>Age:</b> @TempData["Age"]
</div>
Now, run the application, visit the Index page, and then visit either the Privacy or About Page,
as shown in the image below. Both the Index Page and Privacy Page show the Name and
Age values.
If you visit the About page, you will not see the data shown in the image below.
{
TempData["Name"] = "Pranaya";
TempData["Age"] = 30;
//Retention of All keys of TempData for the next request
//TempData.Keep();
//Retention of Individual keys of TempData for the next request
TempData.Keep("Name");
TempData.Keep("Age");
return View();
}
public ActionResult Privacy()
{
//Retention of Individual keys of TempData for the next request
TempData.Keep("Name");
TempData.Keep("Age");
return View();
}
public ActionResult About()
{
//Retention of Individual keys of TempData for the next request
//TempData.Keep("Name");
//TempData.Keep("Age");
return View();
}
}
}
Method 3: Using TempData Peek Method
If we read the data using the string Indexer, the key will be deleted from the TempData
Dictionary Collection by default once we read the value. So, instead of reading the values
using the string Indexer, we can also read the data from TempData using the Peek method.
To do this, we need to pass the key name to the Keep method. In this case, it will read the
data but will preserve the key for the next subsequent request.
To Understand this concept, please modify the Home Controller class as follows. Inside the
Index Action method, we store the data in TempData and redirect the request to the Privacy
Action Method. As the Index View is not executed, we are not fetching the data from the
TempData. So, these TempData keys are available for the next request, which is, in this case,
89
the Privacy Action method. We are fetching the data from the Privacy action method using
the Peek method, which will return the data and keep the keys alive for the next request. And
inside the About Page, we can access the value.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["Name"] = "Pranaya";
TempData["Age"] = 30;
//We are redirecting the request to Privacy Action Method from here
//In this case, Index View is not going to be executed
//Means we are not reading the TempData keys and hence they available
//in the Privacy Action method
//return RedirectToAction("Privacy", "Home");
return RedirectToAction("Privacy");
}
public ActionResult Privacy()
{
//Retention of Individual keys of TempData for the next request
if(TempData.ContainsKey("Name"))
{
//Peek Method will read the data and preserve the key for next request
ViewData["Name"] = TempData.Peek("Name");
}
if (TempData.ContainsKey("Age"))
{
//Peek Method will read the data and preserve the key for next request
ViewData["Age"] = TempData.Peek("Age");
}
return View();
}
90
TempData["MyObject"] = json;
Retrieve and Deserialize the Object
When retrieving the object, get the JSON string from TempData and deserialize it to the
original object type. The following is the syntax.
if (TempData["MyObject"] is string json)
{
var myObject = JsonSerializer.Deserialize<MyComplexObject>(json);
// Use myObject as needed
}
Handling TempData Persistence
If you need the data to persist for another request, you must read it and keep it again. The
syntax is as follows.
string json = TempData["MyObject"] as string;
TempData.Keep("MyObject"); // This line keeps the data for another request
Creating the Model:
First, create the following Student class within the Models folder.
namespace FirstCoreMVCWebApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
Modifying the Home Controller:
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
92
{
public ActionResult Index()
{
//Create the Complex Object
var student = new Student()
{
StudentId = 1,
Name = "Pranaya",
Gender = "Male",
Branch = "CSE",
Section = "A"
};
//Convert the Complex Object to Json
string jsonStudent = JsonSerializer.Serialize(student);
//Store the JSON Objec into the TempData
TempData["StudentObject"] = jsonStudent;
//return RedirectToAction("Privacy", "Home");
return RedirectToAction("Privacy");
}
public JsonResult Privacy()
{
Student? student = new Student();
if (TempData["StudentObject"] is string jsonStudent)
{
//Deserialize the Json Object to Actual Student Object
student = JsonSerializer.Deserialize<Student>(jsonStudent);
//You can use the Student
// The following line keeps the data for another request
TempData.Keep("StudentObject");
}
return Json(student);
}
public JsonResult About()
93
{
Student? std = new Student();
if (TempData["StudentObject"] is string jsonStudent)
{
//Deserialize the Json Object to Actual Student Object
std = JsonSerializer.Deserialize<Student>(jsonStudent);
}
return Json(std);
}
}
}
Now, run the application and test it, and it should work as expected.
How TempData Works in ASP.NET Core MVC?
TempData is stored in short-lived session cookies and is cleared out after it has been read in
a subsequent request. This makes it ideal for passing error messages, status messages, or
other one-time-use data between actions. ASP.NET Core provides several storage providers
for TempData:
• SessionStateTempDataProvider: This is the default provider. It stores
TempData using the session state. To use session-based TempData, you must
enable the session state in your application.
• CookieTempDataProvider: This provider stores TempData in cookies. It’s
useful when you want to avoid using server memory for session state.
However, be aware of the size limitations of cookies.
Post-Redirect-Get (PRG) Pattern Example in ASP.NET
Core
In this article, I will discuss the Post-Redirect-Get (PRG) Pattern Example in the ASP.NET
Core MVC Application with Examples using TempData. Please read our previous article
discussing TempData in ASP.NET Core MVC Application.
What is the Post-Redirect-Get (PRG) Pattern?
The Post-Redirect-Get (PRG) pattern is a web development design pattern that helps prevent
duplicate form submissions and ensures a more user-friendly web application experience. It’s
especially relevant when a user submits form data to a server via an HTTP POST request.
Basic Workflow of PRG Pattern:
• POST Request: The user submits a web form; this sends an HTTP POST
request to the server.
• Server Processing: The server processes the POST request, typically
involving data manipulation like updating a database.
• Redirection: After processing the POST request, the server sends an HTTP
redirect (HTTP status code 302 or 303) to the client instead of a response
directly.
94
• GET Request: Upon receiving the redirect response, the client makes an
HTTP GET request to the specified URL.
• Final Response: The server responds to the GET request with the final
page, which could be a confirmation, result page, or another view.
Post-Redirect-Get (PRG) Pattern using TempData in ASP.NET Core MVC
The Post-Redirect-Get (PRG) pattern is a web development design pattern that helps prevent
duplicate form submissions and ensures that the web page behaves correctly when the user
refreshes it. In ASP.NET Core MVC, the PRG pattern can be implemented using TempData,
which is a way to pass data between controllers and views.
Create a Model
First, you need a model to bind your form data. So, create the following MyModel.cs class
within your Models folder:
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:06 / 03:1110 Sec
namespace FirstCoreMVCWebApplication.Models
{
public class MyModel
{
public string Name { get; set; }
public string Email { get; set; }
// Add other properties as needed
}
}
Create a Controller
In your controller, create two actions – one for displaying the form (HTTP GET) and another
for processing the form (HTTP POST). So, modify the Home Controller as follows:
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
// GET: Display the form
public IActionResult Index()
{
return View();
}
95
<span asp-validation-for="Name"></span>
</div>
<div>
<label asp-for="Email"></label>
<input asp-for="Email" />
<span asp-validation-for="Email"></span>
</div>
<button type="submit">Submit</button>
</form>
Success.cshtml (Success View)
Display the success message. Create a view with the name Success.cshtml within
the Views/Home folder, and then copy and paste the following code:
@{
var message = TempData["SuccessMessage"] as string;
}
@if (!string.IsNullOrEmpty(message))
{
<div>@message</div>
}
<a asp-action="Index">Back to Form</a>
Explanation
• Index Action: Displays the form to the user.
• SubmitForm Action: Process the form submission. If the model is valid, it
processes the data (like saving to a database) and then uses TempData to
store a success message before redirecting to the Success action.
• Success Action: Displays a success message to the user. The message is
retrieved from TempData.
Using the PRG pattern, if the user refreshes the success page, it doesn’t resubmit the form
data. Instead, it simply refreshes the view of the success message. TempData is ideal for this
scenario as it keeps data for the duration of a single redirect and is then automatically
discarded.
Now, run the application, and it should display the following page where you need to enter
the Name and Email and click on the Submit button as shown in the image below:
97
Once you click on the Submit button, it will open the following page and display the successful
message as shown in the below image:
If you verify the Network tab, it will show the following: It will issue a 303 request and then
redirect to the Success page with a 200 status code.
If you refresh the page, you will see that it has not been submitted again.
Advantages of PRG:
98
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:23 / 03:1110 Sec
When the client makes a request, i.e., an HTTP Request, the routing engine first receives it.
Once the Routing engine receives an HTTP Request, the Routing system tries to find the
matching route pattern of the requested URL with already registered routes. Routes contain
information about the Controller name, action method name, method type (Get, Post, Put,
Patch, Delete), method parameters, route data, etc.
99
If it finds a matching URL pattern for the incoming request, it forwards the request to the
appropriate controller and action method. If no match for the incoming HTTP request URL
Pattern is found, it returns a 404 HTTP status code to the client. For a better understanding,
please have a look at the following diagram.
Similarly, if we issue a request to the /Home/Details/2 URL, then the Details action method
of the Home Controller class will handle the request, as shown in the image below. Here, the
parameter value 2 is automatically mapped to the id parameter of the Details action method.
Now, the question that should come to your mind is, we have not explicitly defined any routing
rules for the application. Then how is this mapping done, i.e., how is the /Home/Index URL
101
mapped to the Index action method, and how is the /Home/Details/2 URL mapped to the
Details action method of the Home Controller class? This is done by the MVC Routing
Middleware Component, which we registered into the Request Processing Pipeline
application.
Understanding Routing in ASP.NET Core MVC Application:
First, create an ASP.NET Core Application using the ASP.NET Core Model-View-Controller
Template. To create an ASP.NET Core Web Application with the Model-View-Controller
Project template. First, 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 following Create a new Project window
will open. From this window, select C#, All Platforms, and Web from the respective
dropdowns, as highlighted below. Select ASP.NET Core Web App (Model-View-
Controller), as highlighted below, and click the Next button, as shown in the image below.
102
Once you click on the Next button, it will open the Configure Your New Project window.
Here, you need to provide the necessary information to create a new ASP.NET Core project.
First, give an appropriate name for your project (RoutingInASPDotNetCoreMVC), 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.
The Additional Information window will open once you click on the Next button. Here, you
need to select Framework – .NET 6.0 (Long-term support), Authentication type – None.
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.
103
Once you click the Create button, the project will be created using the Model-View-Controller
template with the following folder and file structure.
104
The default route is created with the following URL Pattern. So, if we don’t specify anything
in the URL, then by default, the Index action method of the Home Controller class will handle
the request.
{controller=Home}/{action=Index}/{id?}
In this example, the MapControllerRoute method defines a default route. The pattern
parameter specifies the route template, where {controller}, {action}, and {id} are
placeholders for route parameters. The name parameter gives the route a name, which can
be used for generating URLs. The meaning of the placeholders are as follows:
• {controller}: Represents the name of the controller class.
• {action}: Represents the action method name within the controller.
• {id?}: Represents an optional route parameter called “id”.
With this configuration, an incoming URL like /Home/Index would match the Index action
method of the HomeController. Similarly, /Products/Details/5 would match the Details action
method of the ProductsController with an id parameter set to 5.
Understanding Route Template in ASP.NET Core MVC Application:
As we see, the default route is created with the URL
Pattern: {controller=Home}/{action=Index}/{id?}
So, the above default route template will map most URLs using the
pattern: http://localhost:52190/Home/Details/2
1. The first segment path of the URL, /Home, is mapped to the HomeController.
As you can see in the URL, we do not have the word Controller with the first
segment path. However, it maps to the HomeController because when
ASP.NET Core MVC Framework finds the word /Home as the first segment
path of the URL, it internally appends the word Controller.
2. The second segment path of the URL, i.e., /Details, is mapped to
the Details(int id) action method of the HomeController class.
3. The third segment path of the URL, i.e., 2, is mapped to the id parameter of
the Details(int id) action method.
As you can see in the default route template {controller=Home}/{action=Index}/{id?}, we
have a question mark at the end of the id parameter, which makes the id parameter optional.
That means the following two requests now map to the same Details action method of the
Home Controller class.
107
/Home/Details/1
/Home/Details
In the default route template {controller=Home}/{action=Index}/{id?}, the
value Home in {controller=Home} is the default value for the Controller. Similarly, the
value Index in {action=Index} is the default value for the action method. That means if we
navigate to the application’s root URL, as shown below, then that request will be handled by
default by the Index action method of the Home Controller class.
http://localhost:52190/
The following two URLs are also mapped to the Index action method of the HomeController
class.
http://localhost:52190/Home
http://localhost:52190/Home/Index
The default route works fine for most of the ASP.NET Core MVC Web Applications. For
example, create a Controller named StudentController and copy and paste the following
code into it.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class StudentController : Controller
{
public string Index()
{
return "Index() Action Method of StudentController";
}
public string Details(int? id)
{
return $"Details({id}) Action Method of StudentController";
}
}
}
Now, the URL /student/index is mapped to the Index() action method of
the StudentController class, and the URL /student/details or /student/details/5 both are
mapped to the Details(int? id) action method of the StudentController.
Configure Multiple Conventional Routing in ASP.NET Core MVC
Application
Configuring Multiple Conventional Routes in an ASP.NET Core MVC application involves
defining multiple route patterns that the application can use to handle incoming requests and
map them to the appropriate controllers and actions. This is done in the Program.cs class
file of your ASP.NET Core project. For example, we want to access the Index Action Method
of the Student Controller using the following URL.
https://localhost:44359/Student/All
108
To achieve this, we can configure the MapControllerRoute method, as shown in the image
below. Here, you can see we have specified the pattern as Student/All and the default
controller and action name as controller = Student, action = Index.
Next, we want to access the Details of the action method for the Student Controller using the
following URL.
https://localhost:44359/StudentDetails/10
To achieve this, we can configure another MapControllerRoute method, as shown in the
below image. Here, you can see we have specified the pattern as StudentDetails/{ID} and
specified the default controller and action name as controller = Student”, action = Details.
For the rest of the controllers and actions, we need to access them using the following URL
Pattern. We also need to configure the default controller and action names as Home and
Index.
https://localhost:44359/{Controller Name}/{Action method Name}
To achieve this, we can configure another MapControllerRoute method, as shown in the
below image. Here, you can see we have specified the pattern
as {controller}/{action}/{id:int?} and specified the default controller and action name
as controller = Home, action = Index.
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//https://localhost:44359/Student/All
app.MapControllerRoute(
name: "StudentAll",
pattern: "Student/All",
defaults: new { controller = "Student", action = "Index" }
);
//https://localhost:44359/StudentDetails/10
app.MapControllerRoute(
name: "StudentIndex",
pattern: "StudentDetails/{ID}",
defaults: new { controller = "Student", action = "Details" }
);
110
//For Rest of the Controller Actions including the Default Home Controller Index
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id:int?}",
defaults: new { controller = "Home", action = "Index" }
);
app.Run();
}
}
}
With the above changes in place, run the application and navigate to the specific URLs, and
you will get the data as expected.
Points to Remember While Defining Multiple Conventional Routing
• Route Order Matters: Routes are evaluated in the order they are defined.
Ensure the most specific routes are defined first, as the request will be handled
by the first route it matches.
• Naming Routes: It’s a good practice to give each route a unique name. This
helps when generating URLs based on route names.
• Defaults: You can specify controller, action, and parameter default values.
This is useful for defining fallbacks for missing parts of the route.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:14 / 03:1110 Sec
111
With the above Custom Routing in Place, when we run the application, it will not access the
Home Controller Index Action method by default. That means it will not access any controller
action method by default. The above MapControllerRoute is the simplest possible convention-
based route for an ASP.NET Core MVC Web Application. Now run the application and
navigate to the following URLs, and you will see the output as expected. You need to change
the port number.
https://localhost:44359/Student/Details
https://localhost:44359/Student/Index
This is working fine. However, what if we wanted to have more specific routes? Say
something like the following URLs:
https://localhost:44359/Student/Details/20
https://localhost:44359/Student/Index/10
If you want your controller action methods to match the above URLs, you need to use a Route
Constraints feature in the ASP.NET Core MVC Application.
Route Constraints in ASP.NET Core MVC Web Application:
Route constraints in ASP.NET Core MVC are important in controlling the flow of HTTP
requests to route handlers based on specific conditions. Constraints allow you to restrict the
values that are accepted by route parameters, ensuring that the route is only matched for
valid inputs. These constraints ensure that a route will only match and subsequently invoke
an action method if the incoming request meets all specified criteria.
Route constraints are defined within the route template, either inline within the route definition
or as part of the route configuration. Constraints can check for various conditions, including
data types, value ranges, pattern matching, and custom validation logic.
Implementing Route Constraints in ASP.NET Core MVC:
Route constraints are used in both attribute-based and conventional-based routing to ensure
that the values provided in the URL match the expected data types or formats. Let’s say we
want to create a route matching the following URLs.
https://localhost:44359/Student/Details/20
https://localhost:44359/Student/Index/10
We can achieve this in two ways: Attribute Routing and Conventional Routing. In our
upcoming articles, we will discuss how to achieve the same using Attribute Routing. In this
article, let us see how we can achieve the same using Conventional Routing in ASP.NET
Core MVC Web Applications.
112
As we make the action method mandatory for taking the ID parameter value, we need to
change the action methods of our controller with the ID parameter. So, modify the
StudentController class as shown below.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class StudentController : Controller
{
public string Index(string id)
{
return $"Index({id}) Action Method of StudentController";
}
public string Details(string id)
{
return $"Details({id}) Action Method of StudentController";
}
}
}
With the above changes in place, now run the application and navigate to the following URLs,
and you will see that methods are executed as expected.
https://localhost:44359/Student/Details/20
https://localhost:44359/Student/Index/10
113
This is working fine. But, the problem with the above route is that it can accept any value.
Instead of an integer, if you pass a string value, it also accepts and executes the action
methods, as shown below.
https://localhost:44359/Student/Details/ABC
https://localhost:44359/Student/Index/ABC
If you want to restrict the id parameter value to be an integer only, then you need to use a
concept called Route Constraint in ASP.NET Core. So, what we need to do is, while
defining the Route, we can explicitly tell that this parameter is going to accept only integer,
boolean, or any particular data type value.
In our example, we want to restrict the id parameter to accept only integer values. So, we
need to modify the MapControllerRoute Middleware Component as follows. As you can see,
as part of the pattern, we specify the id parameter to accept int values only (pattern:
“{controller}/{action}/{id:int}”). This is called inline Route Constraint. Inline constraints are
specified directly within the route template by appending a colon (:) followed by the constraint
name to a route parameter.
want to mark the id parameter as an optional parameter and accept only integer values. So,
in the URL pattern, we need to specify the id parameter as “id:int?“. We need to modify
the MapControllerRoute Middleware Component as follows.
Here, “id:int?” says that id is an optional parameter, but if you pass any value, it should be
of type integer. You can define only one optional parameter per route, which must be the last
parameter. With the above changes in place, now run the application and navigate to the
following URLs, and you will get the data as expected.
https://localhost:44359/Student/Index
https://localhost:44359/Student/Details
https://localhost:44359/Student/Details/10
How Do We Provide Default Route Values in the ASP.NET Core MVC
application?
Default Route values are useful when you have optional route parameters. As of now, you
can observe that whenever we run the application, by default, it loads the base URL
(https://localhost:44359/) of the application and gives us a 404 error. This is because we
have not set any default values for our Route parameter. If we have not specified the name
of the controller or action method in the URL, what should the controller and action method
execute?
Let us proceed and understand how we can specify the default values for our Route
Parameter so that if we do not specify the Controller or Action method name in the URL or
when the application launches, it should take the default values from the Route and execute
the action method.
So, using Default values, we can specify what happens if parts of the route are not provided
in the URL. For example, when we navigate to the following two URLs
https://localhost:44359/
https://localhost:44359/Home
We want to map the above two URLs to the Home Controller and Index action method of the
Application. To do so, we need to specify the default controller and action method name in
the MapControllerRoute Middleware Component URL Pattern. So, modify
the MapControllerRoute Middleware Component within the Main method of the Program
class as follows. Here, we have specified the default controller name as Home, the default
action method name as Index, and Id as the Route parameter, which is optional as well as
that parameter can accept only integer values (pattern:
“{controller=Home}/{action=Index}/{id:int?}“).
116
With the above changes in place, now run the application and visit the following two URLs,
and you should get the output as expected.
https://localhost:44359/
https://localhost:44359/Home
You can also map the default values for the route parameter by using the defaults parameter
of the MapControllerRoute Extension method, as shown in the image below.
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "CustomRoute",
pattern: "{controller}/{action}/{id:int?}",
defaults: new { controller = "Home", action = "Index" }
);
app.Run();
}
}
}
With the above changes in place, run the application, and it should work as expected.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
}
else
{
return false;
}
}
return false;
}
}
}
Register the Custom Route Constraint:
Before using the Custom Route Constraint, we need to register it with the Routing System.
This is typically done in the Program.cs file. We need to register the Custom Route Constraint
within the ConstraintMap dictionary. The ConstraintMap is a dictionary that contains the list
of built-in route constraints. So, we have to add our Custom Route Constraint to this
ConstraintMap dictionary with the help of route options. We can register the Custom Route
Constraint service to the built-in dependency Injection container in two ways. They are as
follows:
Method 1: Configuring the Custom Route Constraint Service using the AddRouting
Method
builder.Services.AddRouting(options =>
{
options.ConstraintMap.Add("alphanumeric", typeof(AlphaNumericConstraint));
});
Method 2: Configuring the Custom Route Constraint Service using the Configure
Method
builder.Services.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add("alphanumeric", typeof(AlphaNumericConstraint));
});
Use the Custom Route Constraint in Route Configuration:
Once you register the Custom Route Constraint, then you can use the Custom Route
Constraint in the Route Template. You have to use the “:” separator between the route
parameter and constraints. For example, you can use the alphanumeric (whatever name you
provided while registering the service) route constraint as follows:
app.MapControllerRoute(
name: "CustomRoute",
121
pattern: "{controller}/{action}/{id:alphanumeric?}",
defaults: new { controller = "Home", action = "Index" }
);
In the above code, we have specified the id parameter with Custom Route Constraint
alphanumeric and made this parameter optional.
using RoutingInASPDotNetCoreMVC.Models;
namespace RoutingInASPDotNetCoreMVC
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
//Configuring the Custom Route Constraint Service using AddRouting Method
builder.Services.AddRouting(options =>
{
options.ConstraintMap.Add("alphanumeric", typeof(AlphaNumericConstraint));
});
//Configuring the Custom Route Constraint Service using Configure Method
//builder.Services.Configure<RouteOptions>(routeOptions =>
//{
// routeOptions.ConstraintMap.Add("alphanumeric",
typeof(AlphaNumericConstraint));
//});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
122
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "CustomRoute",
pattern: "{controller}/{action}/{id:alphanumeric?}",
defaults: new { controller = "Home", action = "Index"}
);
app.Run();
}
}
}
Note: You can use the Custom Route Constraint in both Convention-Based and Attribute-
Based Routing in ASP.NET Core Application.
Next, modify the Student Controller as follows. Now, you can access the Index and Details
action method without passing any route values. However, if you want to pass route values
for the Details action method, the value should be alphanumeric; otherwise, it will give a 404
Resource Not Found Error.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class StudentController : Controller
{
public string Index()
{
return $"Index() Action Method of StudentController";
}
public string Details(string id)
{
return $"Details({id}) Action Method of StudentController";
}
}
123
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:31 / 03:1110 Sec
Adding Student Model:
First, add a class file named Student.cs, within the Models folder, and copy and paste the
following code.
namespace RoutingInASPDotNetCoreMVC.Models
{
public class Student
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Modifying Student Controller:
We have already created the Student controller within the Controllers folder. If not, please
right-click on the Controllers folder and add a new ASP.NET Core MVC Empty controller
named StudentController.cs, and then copy and paste the following code.
using Microsoft.AspNetCore.Mvc;
using RoutingInASPDotNetCoreMVC.Models;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
124
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id:int?}",
defaults: new { controller = "Home", action = "Index" }
);
app.Run();
}
}
}
Now, you can access the three action methods of the Student Controller using the following
URLs, and it will work as expected.
https://localhost:44359/Student/GetAllStudents
https://localhost:44359/Student/GetStudentByID?studentID=1
https://localhost:44359/Student/GetStudentCourses?studentID=1
In some scenarios, Convention-Based routing makes it very difficult to support certain URL
patterns. However, attribute routing in the ASP.NET Core MVC application can easily achieve
those URL patterns.
In our example, if we want the URL Pattern “/student/1/courses” and if that URL Pattern
should be mapped to GetStudentCourses(int studentID), then this type of URL Pattern is
very difficult to create using convention-based routing in an ASP.NET Core MVC Application.
However, we can easily achieve this type of URL pattern by using attribute routing in an
ASP.NET Core MVC application.
How Do We Use Attribute Routing in ASP.NET Core MVC?
Attribute routing allows us to define routes directly on our controller and action methods using
the Route Attributes. Applying the Route attribute at the Controller level applies to all the
controller’s action methods. We can also use the [HttpGet], [HttpPost], [HttpPut],
[HttpDelete], and [HttpPatch] Attributes at the action method level to define the Route
Pattern. Let us first modify the Student Controller as shown below. Here, we have applied the
Route Attribute at the Action methods level.
using Microsoft.AspNetCore.Mvc;
using RoutingInASPDotNetCoreMVC.Models;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class StudentController : Controller
{
//This is going to be our data source
//In Real-Time you will get the data from the database
static List<Student> students = new List<Student>()
127
{
new Student() { Id = 1, Name = "Pranaya" },
new Student() { Id = 2, Name = "Priyanka" },
new Student() { Id = 3, Name = "Anurag" },
new Student() { Id = 4, Name = "Sambit" }
};
//This method is going to return all the Students
//URL Pattern: /Student/All
[Route("Student/All")]
public List<Student> GetAllStudents()
{
return students;
}
//This method is going to return a student based on the student id
//URL Pattern: /Student/1/Details
[Route("Student/{studentID}/Details")]
public Student GetStudentByID(int studentID)
{
//Returning the First Student Information
Student? studentDetails = students.FirstOrDefault(s => s.Id == studentID);
return studentDetails ?? new Student();
}
//This method is going to the courses of a student based on the student id
//URL Pattern: /Student/1/Courses
[Route("Student/{studentID}/Courses")]
public List<string> GetStudentCourses(int studentID)
{
//Real-Time you will get the courses from database, here we have hardcoded the data
List<string> CourseList = new List<string>();
if (studentID == 1)
CourseList = new List<string>() { "ASP.NET Core", "C#.NET", "SQL Server" };
else if (studentID == 2)
CourseList = new List<string>() { "ASP.NET Core MVC", "C#.NET", "ADO.NET Core" };
128
else if (studentID == 3)
CourseList = new List<string>() { "ASP.NET Core WEB API", "C#.NET", "Entity
Framework Core" };
else
CourseList = new List<string>() { "Bootstrap", "jQuery", "AngularJs" };
return CourseList;
}
}
}
With the above Attribute Routing in place, we can now access the above three action methods
for the student controller using the following URLs.
https://localhost:44359/Student/All
https://localhost:44359/Student/1/Details
https://localhost:44359/Student/1/Courses
Can we Apply Multiple Route Attributes to a Single Action Method in
ASP.NET Core MVC?
Yes, we can apply Multiple Route Attributes to a Single Action Method in the ASP.NET Core
MVC Application. Let us understand this with an example. Please modify the Home Controller
as shown below, and please have a look at the Index Action method, where we have applied
three attributes.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
}
}
If you notice, we have applied the Route attribute three times to the Index() action method of
the Home Controller class. With each instance of the Route attribute, we specified a different
route template. With the above three Route attributes applied to the Index action method, we
129
can now access the Index() action method of the HomeController using the following three
URLs.
https://localhost:44359/
https://localhost:44359/home
https://localhost:44359/home/index
If you apply the same Route Attributes multiple times with an Action Method and if you apply
the same Route Template to different action methods, then you will
get AmbiguousMatchException. Now run the application and navigate to the above three
URLs, and you will see the Home page as expected.
Attribute Routing with Parameters in ASP.NET Core MVC Application:
As we already discussed, we can specify the Route Parameters as part of the route template
with Conventional-Based Routing. We can also do the same with Attribute Routing in
ASP.NET Core. That means we can also define Route Attributes with Route Parameters. To
understand this, modify the Home Controller as shown below.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[Route("Home/Details/{id}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
}
}
As you can see in the above code, the Details() action method has the id parameter. Notice
that in the route template, we also specified the ID parameter
([Route(“Home/Details/{id}”)]). So, the URL (/Home/Details/10) will execute
the Details(int id) action method and map the value 10 to the id parameter of the Details
action method. This is done through the model binding process, which will be discussed in
our upcoming articles. Run the application and navigate to the following URL; you should see
130
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[Route("Home/Details/{id=10}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
}
}
If you run the application and navigate to the URL below without specifying the ID parameter,
it will take the default value 10.
https://localhost:44359/Home/Details
Controller and Action Method Names in Attribute Routing:
With Attribute Routing in ASP.NET Core MVC Application, the Controller and Action Method
names do not play any role. To understand this, modify the Home Controller as shown below.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("MyHome")]
[Route("MyHome/Index")]
public string StartPage()
{
return "StartPage() Action Method of HomeController";
132
}
}
}
As you can see, we have specified the Route attribute three times with the StartPage() action
method of the HomeController. So, this StartPage action method will be executed for the
following 3 URLs.
https://localhost:44359/
https://localhost:44359/home
https://localhost:44359/home/index
Can we use both Attribute and Convention-Based Routing in a Single
ASP.NET Core MVC Application?
Yes. Both routing mechanisms can be combined in a single ASP.NET Core MVC Web
Application. The controller action methods with the [Route] attribute use Attribute Routing,
and those without the [Route] attribute use Convention-based routing. To better understand,
please modify the Home Controller class as shown below.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("MyHome")]
[Route("MyHome/Index")]
public string StartPage()
{
return "StartPage() Action Method of HomeController";
}
public string Privacy()
{
return "Privacy() Action Method of HomeController";
}
}
}
As you can see in the above code, we have applied the Route Attribute with the StartPage
action method, and we have not applied the Route Attribute with the Privacy action method.
So, in this case, StartPage will use Attribute Routing, and we can access this method using
the following 3 URLs.
133
https://localhost:44359/
https://localhost:44359/home
https://localhost:44359/home/index
On the other hand, the Privacy action method will use Contention-Based Routing and can be
accessed by using the following URL only.
https://localhost:44359/home/privacy
Note: It is not possible to access an action method using both Attribute and Convention
Routing. If Attribute Routing is applied to an action method, then you can access that method
using Attribute Routing only; you cannot access the same method using Convention Routing.
Similarly, if Attribute Routing is not applied to an action method, then you can access that
method using Conventional Routing only; you cannot access the same method using Attribute
Routing.
Applying Route Attribute at the Controller Level in the ASP.NET Core
MVC:
In the ASP.NET Core MVC Web Application, applying the Route() Attribute to the Controller
class and individual action methods is possible. If you want to make attribute routing less
repetitive, you need to use the Route Attribute on the controller level. Let us understand this
with an example. First, modify the Home Controller class, as shown below. Here, we have
created the Home controller with two action methods.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[Route("Home/Details/{id?}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
}
}
134
With the above code in place, we can access the Index() action method using the following
3 URLs.
/
/Home
/Home/Index
Along the same line, we can access the Details(int? id) action method using the following 2
URLs.
/Home/Details
/Home/Details/2
If you look at our code, you will see that we are using Route Attributes at the action method
level to define routes. Further, you will notice that all the routes in the HomeController start
with the same prefix, i.e., Home. That means Home is the common prefix for all the routes in
the Home Controller.
Here, instead of writing the common prefix Home at each action method, we can specify the
Home for the Home Controller (for all its action methods) using the [Route] attribute at the
controller level.
So, modify the Home Controller class as follows. Here, you can see we have
applied [Route(“Home”)] at the controller level, and we have removed that Home prefix from
each action method Route Attribute. The Route Attribute we define at the Controller level will
be applied to each action method.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[Route("Details/{id?}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
}
}
135
The Route template applied on the controller level is prepended to the route template applied
to the action method level. When you navigate to the following four URLs, you will get the
output as expected.
https://localhost:44359/home
https://localhost:44359/home/index
https://localhost:44359/home/details
https://localhost:44359/home/details/10
However, when you navigate to the application’s root URL (http://localhost:44359), you will
get a 404 error. To solve this, you need to include the route template that begins with
“/” i.e. [Route(“/”)] on the Index() action method, as shown in the image below.
}
}
With the above changes in place, run the application and navigate to the root URL to see the
expected output. As you can see in the above code, we have applied
the [Route(“Home”)] attribute at the Controller level. This Route attribute eliminates the
need to repeat the common prefix “Home” on each controller action method. However,
sometimes, we may need to override the route attribute defined at the controller level.
How Do We Ignore the Route Attribute Placed at the Controller Level in
ASP.NET Core MVC?
To ignore the Route Template placed at the Controller level, you must use / or ~/ at the action
method level. If the action method route template starts with / or ~/, then the controller Route
Attribute will not be combined with the action method route attribute. To understand this, let
us modify the Home Controller class as shown below. In the following code, the About action
method starts with ~/, so this action method will not be combined with the controller route
attribute.
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("/")]
[Route("Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[Route("Details/{id?}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
[Route("~/About")]
public string About(int id)
{
return "About() Action Method of HomeController";
137
}
}
}
Now run the application and navigate to /About URL, and you will see the output as expected.
Defining Route using HTTP Methods:
We can also achieve this using HTTP Verbs. So, let us rewrite the previous example using
HTTP Methods as follows:
using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
[Route("Home")]
public class HomeController : Controller
{
[HttpGet("")]
[HttpGet("/")]
[HttpGet("Index")]
public string Index()
{
return "Index() Action Method of HomeController";
}
[HttpGet("Details/{id?}")]
public string Details(int id)
{
return "Details() Action Method of HomeController, ID Value = " + id;
}
[HttpGet("~/About")]
public string About(int id)
{
return "About() Action Method of HomeController";
}
}
}
What is the Difference Between [Route] and [HttpGet], [HttpPost], etc.,
Attributes?
138
The [Route] attribute specifies a route template for a controller or action method but does not
apply any specific HTTP method. On the other hand, HTTP method attributes like [HttpGet],
[HttpPost], [HttpPut], and [HttpDelete] not only define the route template but also restrict the
action method to be invoked only with the specified HTTP method.
namespace FirstCoreMVCApplication.Controllers
//Using token controller at the Controller level using the Route Attribute
[Route("[controller]")]
//Using token action at the Action Method level using the Route Attribute
[Route("[action]")]
//Using token action at the Action Method level using the Route Attribute
[Route("[action]")]
}
With the above controller and action tokens in place with the Route Attribute, you can now
access the Index action method of the Home Controller with the URL /Home/Index. Similarly,
you can access the Details action method of the Home Controller using the
URL /Home/Details.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
• The route for the Index action method would be /Home/Index because of the
[controller] and [action] tokens used in the controller’s route attribute.
• The route for the Details action method would be /Home/Details because of
the [controller] and [action] tokens used in the controller’s route attribute.
Now, run the application and see if everything is working as expected. The token controller
will be replaced with the actual controller name, and similarly, the token action will be replaced
with the actual action method name.
How Do We Make the Index Action Method the Default Action?
With the controller and action tokens in place with Route Attribute, if you want to make the
Index action method of Home Controller the default action, then you need to include
the [Route(“/”)] attribute with an “/” on the Index action method. So, modify the Home
Controller as shown below and rerun the application. It should display the Index Action
method.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCApplication.Controllers
//Using token controller at the Controller level using the Route Attribute
140
[Route("[controller]")]
//Using token action at the Action Method level using the Route Attribute
[Route("/")] //This will make the Index Action method as the Default Action
[Route("[action]")]
//Using token action at the Action Method level using the Route Attribute
[Route("[action]")]
}
Do We Need to Write the Action Token for Each Action Method?
Not Really. If you want all your action methods to apply the action token, then instead of
applying the [action] token on each and every action method, you can apply it only once on
the controller. So, in this case, the Route attribute at the controller level should include both
controller and action tokens like [Route(“[controller]/[action]”)]. So, modify the Home
Controller class as shown below to apply the controller and action tokens at the controller
level.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCApplication.Controllers
141
//Using controller and action tokens at the Controller level using the Route Attribute
[Route("[controller]/[action]")]
//This will make the Index Action method as the Default Action
[Route("/")]
}
Now, run the application, and it should work as expected.
Advantages of Using Tokens in ASP.NET Core Attribute Routing:
Attribute routing with tokens provides a flexible and expressive way to define dynamic routes
in your ASP.NET Core MVC application. The following are the advantages of using Token
with Attribute Routing in ASP.NET Core Web Applications:
• Reduction of Redundancy: Tokens help reduce redundancy by eliminating
the need to repeat the controller or action names in each route definition.
• Maintainability: Changing the name of a controller or action only requires
updating the class or method name, not the routes.
• Clarity: Route templates with tokens are generally easier to read and
understand, as they directly relate to the controller and action names.
142
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:21 / 03:1110 Sec
Characteristics of Attribute Routing:
• Routes are defined using attributes on controllers and actions, allowing for
detailed and customized route definitions.
• It offers greater flexibility in defining routes that do not follow a conventional
pattern.
• Supports the definition of complex route templates, including using multiple
parameters, constraints, and even dynamically generating URLs.
Advantages of Attribute Routing:
• Provides greater control and precision over routing, allowing for complex and
custom route patterns that are not easily achieved with conventional routing.
• Facilitates the organization of routing logic by keeping it closer to the action
methods it applies to, improving readability and maintainability.
Disadvantages of Attribute Routing:
• This can lead to a scattered routing configuration if not managed carefully, as
routes are defined across different controllers and actions.
• It requires more effort to understand the routing configuration as it is not
centralized.
When to use Attribute Routing:
• Fine-grained URL Control: When you need precise control over your
application’s URL patterns, attribute routing is the way to go. It’s particularly
useful for designing RESTful APIs where URLs represent resources and
operations on those resources.
• Complex Route Patterns: Attribute routing shines when dealing with
complex routes that conventional routing struggles with, such as routes that
need to capture multiple parameters or have custom constraints.
• Versioning APIs: For applications that involve API versioning, attribute
routing makes it easier to define different routes for different API versions within
the same application.
• Mixing Static and Dynamic Segments: If you need to mix static URL
segments with dynamic ones in a single route, attribute routing provides the
flexibility to accomplish this easily.
The choice between attribute routing and conventional routing depends on your application’s
specific needs. Conventional routing is often more suitable for applications that benefit from
centralized route definitions and have a uniform URL structure. On the other hand, attribute
routing is preferred for applications requiring detailed control over route configurations, such
as APIs or applications with complex routing requirements. It’s also worth noting that
ASP.NET Core supports combining both routing methods in the same application, allowing
developers to choose the most appropriate routing strategy for each controller or action.
144
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:33 / 03:1110 Sec
If you don’t have a layout view for your website, then you need to repeat the required HTML
for the above-mentioned sections in each and every view of your application. This violates
the DRY (Don’t Repeat Yourself) principle as we are repeating the same code in multiple
views.
145
As a result, it isn’t easy to maintain the application code. For example, suppose you have to
remove or add a menu item from the list of navigation menus or even if you want to change
the header or footer of your website. In that case, you need to do this in every view, which is
tedious, time-consuming, and error-prone.
Instead of putting all the sections (i.e., the HTML) in every view page, it is always better and
advisable to put them in a layout view and then inherit that layout view in every view where
you want that look and feel. With the help of layout views, it is now easier to maintain your
application’s consistent look and feel. This is because if you need to make any changes, you
need to do it only in one place, i.e., in the layout view, and the changes will be reflected
immediately across all the views inherited from the layout view.
How Do We Create a Layout View in ASP.NET Core MVC Application?
First, create a new ASP.NET Core Application named FirstCoreMVCApplication using the
Model-View-Controller Template. Next, follow the steps below to create a layout view in
ASP.NET Core MVC.
1. Right-click on the “Views” folder and then add a new folder named “Shared”
if not already added. If you are creating the ASP.NET Core Web Application
using Model-View-Controller, the Shared folder will be there with
the _Layout.cshtml file by default.
2. Next, Right-click on the “Shared” folder and select the “Add” – “New
Item” option from the context menu. This will open the Add New Item window.
3. From the “Add New Item” window, search for Layout and then select “Razor
Layout.” Give your layout view a meaningful name (_Layout.cshtml), and
finally, click on the “Add” button, as shown below. This should add
the _Layout.cshtml file to the Shared folder.
Note: In this article, I will show you how to create and use a layout file. In our upcoming
articles, I will also show you how to use a website header, footer, and navigation menus. So,
once you add the _Layout.cshtml file, your Views folder should look as shown below.
146
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<table border="1" style="width:800px; font-family:Arial">
<tr>
<td colspan="2" style="text-align:center">
<h3>Website Header</h3>
</td>
</tr>
<tr>
<td style="width:200px">
<h3>Left Navigation Menus</h3>
</td>
<td style="width:600px">
@RenderBody()
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center; font-size:x-small">
<h3>Website Footer</h3>
</td>
</tr>
</table>
</body>
</html>
Configuring MVC Services and Middleware in the Main Method of the
Program class:
Please modify the Main method of the Program class, as shown below, to configure the
required MVC services and Middleware Components. Here, we are using the
AddControllersWithViews method to configure MVC services. We have also used
the UseRouting and MapControllerRoute middleware components to configure the
148
Routing and MVC Middleware to the Request Processing Pipeline. Also, we set the Home
controller and Index action method as the default route for our application.
namespace FirstCoreMVCApplication
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
}
}
}
Modifying the Home Controller:
The Home Controller class is created by default. Please modify it as shown below. We have
created the Home Controller class with two action methods: Index and Details. Both action
methods return a view.
149
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
public ViewResult Details()
{
return View();
}
}
}
How to Use Layout View in ASP.NET Core MVC Application?
Now, we will create the Index and Details views using the Layout view. We need to set
the Layout property to render a view using the layout view (_Layout.cshtml).
Index.cshtml:
Please modify the Index.cshtml view as shown below to use the layout view. Here, we are
setting the Page Title using the ViewBag.Title property, i.e., ViewBag.Title = “Home
Page”; and we are also setting the Layout for our view as Layout =
“~/Views/Shared/_Layout.cshtml”;
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Home Page</h1>
Details.cshtml:
Please create the Details.cshtml view within the Views/Home folder and then copy and
paste the following code to use the layout view. Here, we are setting the Page Title using
the ViewBag.Title property, i.e., ViewBag.Title = “Details Page”; and we are also setting
the Layout for our view as Layout = “~/Views/Shared/_Layout.cshtml”;
@{
ViewBag.Title = "Details Page";
Layout = "~/Views/Shared/_Layout.cshtml";
150
}
<h1>Details Page</h1>
Now run the application and navigate to the Home/Index URL, which should display the page
below.
Next, navigate to the Home/Details URL, which should display the page below.
If you compare both pages, you will see that only the Page Title and Main Content area are
changed; the rest, like the Footer, Menus, and Header, will be the same. Here, we are not
repeating the HTML code in both the Index and Details View; rather, we are using the Layout
view, which contains the common HTML Elements.
151
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:18 / 03:1110 Sec
In general, all the static files of our ASP.NET Core MVC Application need to be placed within
this wwwroot folder. Once you have created the “wwwroot” folder, create a subfolder within
it with the name “js” if it is not already there, and then add a Javascript file with the
name “CustomJavascript.js” within the js folder.
To do so, right-click on the js folder and select Add => New Item from the context menu,
which will open the New Item window. Here, search javascript, select Javascript File, give the
file name CustomJavascript.js, and finally click the Add button, as shown in the image
below.
152
Once you add the CustomJavascript.js file, your wwwroot folder should look as shown in
the image below.
Situation 1:
If we have a custom Javascript file (e.g., CustomJavascript.js) and all the views of our
application require that file, we need to place that file in the Layout View of our application.
Let us add that CustomJavascript.js file within our _Layout.cshtml file. So, modify
the _Layout.cshtml file as follows.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
153
</head>
<body>
<table border="1" style="width:800px; font-family:Arial">
<tr>
<td colspan="2" style="text-align:center">
<h3>Website Header</h3>
</td>
</tr>
<tr>
<td style="width:200px">
<h3>Left Navigation Menus</h3>
</td>
<td style="width:600px">
@RenderBody()
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center; font-size:x-small">
<h3>Website Footer</h3>
</td>
</tr>
</table>
<script src="~/js/CustomJavascript.js"></script>
</body>
</html>
Note: Putting all the script files before the closing body tag is always a good programming
practice.
Situation 2:
Suppose we have a custom Javascript file (e.g., CustomJavascript.js), and we want this file
to be used in some specific views. Let’s assume we want this file in the Index view but not in
the Details view of the Home Controller. In such scenarios, we can use the Section in the
ASP.NET Core MVC Application.
Understanding the RenderSection and RenderSectionAsync Method:
To use Section in ASP.NET Core MVC Layout Views, we are provided with
the RenderSection and RenderSectionAsync methods. Let us look at the signatures of the
RenderSection and RenderSectionAsync methods, shown below.
154
As you can see, two overloaded versions of the RenderSection Method exist. The same is
the case for the RenderSectionAsync method. The first version of the Render section
method takes a single parameter (i.e., name) that specifies the section’s name. The second
overloaded version takes two parameters. The first parameter (name) specifies the section’s
name, while the second parameter (required) specifies whether the section is required or
optional.
• name: The name of the section that you want to render.
• required: A boolean value indicating whether the section is mandatory. If set
to true, an exception is thrown if the section is not defined on the content page.
If set to false, the layout will render without the section if it’s not present on the
content page.
How Do We Use the RenderSection Method in ASP.NET Core MVC?
From your layout view, you need to call the RenderSection() method at the location where
you want the section content to be rendered. For example, we want the script file to be
included before the closing </body> tag. So, here, we are calling
the @RenderSection() method just before the closing </body> tag, as shown below.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<table border="1" style="width:800px; font-family:Arial">
<tr>
<td colspan="2" style="text-align:center">
<h3>Website Header</h3>
</td>
</tr>
<tr>
<td style="width:200px">
<h3>Left Navigation Menus</h3>
</td>
<td style="width:600px">
@RenderBody()
155
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center; font-size:x-small">
<h3>Website Footer</h3>
</td>
</tr>
</table>
@RenderSection("Scripts")
</body>
</html>
In the above code, we use the first overloaded version of the RenderSection method, which
only takes the name parameter. In this case, the second parameter value will be true by
default. That means it is a mandatory section.
How to Provide Section Content in a Child View?
We have created a section in our layout view. Now, let us understand how to provide section
content from the Child Views. Each view that wants to provide section content must include
a section within the view. We need to use the @section directive to include the section and
provide the content to do this.
In our example, we want to provide the section content from the Index view. So, modify the
Index view as shown below. Here, you can see we are using @section Scripts {<script
src=”~/js/CustomJavascript.js”></script>} as we are trying to include a javascript file.
Here, we need to provide the section name as Scripts, and this is because, in
the _Layout view, we have specified the section name as Scripts,
i.e., @RenderSection(“Scripts”)
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Home Page</h1>
@section Scripts {
<script src="~/js/CustomJavascript.js"></script>
}
Now run the application and navigate to the Home/Index URL, and you will see the out as
expected, as shown in the below image.
156
But, when you navigate the Home/Details URL, you will get the following error page.
The reason for getting the above exception is the section is mandatory, and we have not
specified the section content in the Details view. To verify this, go to the definition of
the RenderSection(“Scripts”) method, which takes the string file name as a parameter, and
you will see the following. As you can see, this method takes only the name parameter, and
internally, it sets the required parameter value to true, making it mandatory to include the
section in the child view. And in the Details view, we have not included any section.
</tr>
</table>
@RenderSection("Scripts", false)
</body>
</html>
With the above changes in place, run the application and navigate to both URLs. You should
get the output as expected.
Option 2: Using the IsSectionDefined() method.
This method returns a value indicating whether the specified section is defined on the child
view. If the section is defined in the child view, then the IsSectionDefined() method returns
true, and in that case, the RenderSection method loads the content from the child view. If the
method returns false, then the RenderSection method is not going to be executed and be
ignored. So, modify the _Layout.cshtml file as shown below.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<table border="1" style="width:800px; font-family:Arial">
<tr>
<td colspan="2" style="text-align:center">
<h3>Website Header</h3>
</td>
</tr>
<tr>
<td style="width:200px">
<h3>Left Navigation Menus</h3>
</td>
<td style="width:600px">
@RenderBody()
</td>
</tr>
<tr>
159
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
Suppose you want to use a different Layout for all 100 views tomorrow. Then, you need to
update the Layout Property in each individual view of your application. This process is
tedious, time-consuming, and error-prone because you may miss updating the Layout
Property in some views. To solve the above problems, we need to use
the _ViewStart.cshtml file.
How to Create _ViewStart.cshtml file in ASP.NET Core MVC Application?
The _ViewStart.cshtml files are created within the Views or the Views folder’s subfolder. To
create the _ViewStart.cshtml file, right-click on the Views folder and then select the Add –
New Item option from the context menu; this will open the New Item window. From the New
Item window, search for Razor and then select the Razor View Start template, provide the
name as _ViewStart.cshtml, and click on the Add button as shown in the below image,
which should create the _ViewStart.cshtml file within the Views folder of your project.
If you are creating the ASP.NET Core Application using the Model-View-Controller Project
template, then by default, the _ViewStart.cshtml file is added within the Views folder, as
shown in the image below.
162
Once you create the _MyLayout.cshtml file, copy and paste the following code.
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
@if (IsSectionDefined("Scripts"))
{
@RenderSection("Scripts")
}
</body>
</html>
With this Layout, we now have two layouts (_Layout.cshtml and _MyLayout.cshtml) for our
application.
Creating Another ViewStart File within the Home Folder:
164
Let’s add another ViewStart file within the Home Folder, which is present within
the Views folder. Once you create the ViewStart file, then modify the file as shown below.
Here, we are setting the newly created _MyLayout.cshtml layout using the Layout property.
@{
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
With the above changes in place, your application’s Views folder should look like the image
below.
As you can see in the above image, we have placed one ViewStart file inside
the Views folder and another inside the Home sub-folder. Now run the application and
navigate to the Home/Index URL, as shown in the image below.
The above Index view of the Home Controller uses MyLayout.cshtml view, which we
specified within the _ViewStart.cshtml File, which is present inside the Home Folder. So,
here, the Layout Page, specified in the _ViewStart.cshtml file in the Home sub-folder,
165
overwrites the Layout Page, which is specified in the _ViewStart.cshtml File in the Views
folder.
This means all the views in the Views folder will use the layout page specified in
the _ViewStart.cshtml file in the Views folder, but the views in the Home folder will use the
layout page specified in the _ViewStart.cshtml File in the Home folder.
How to Use a Different Layout Other the Layout Specified in the
_ViewStart.cshtml File?
To use a different layout than the one specified in the _ViewStart.cshtml file, we need to set
the layout explicitly in individual view files. If you don’t want to use the layout file specified in
the _ViewStart file either from the Home folder or the Views folder, you want to use a different
layout file; then you need to use the Layout property in the individual view to set the layout.
Let us understand this with an example. Create another Layout with the
name _NewLayout.cshtml within the Shared Folder. Once you create
the _NewLayout.cshtml file, copy and paste the following code.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
<h4>This View Using _NewLayout.cshtml</h4>
@RenderBody()
</div>
</body>
</html>
I want to use the above _NewLayout.cshtml in the Details View of our Home Controller. To
do so explicitly, we need to use the Layout property and provide the path of
the _NewLayout.cshtml file. So, modify the Details.cshtml file as follows.
@{
ViewBag.Title = "Details Page";
Layout = "~/Views/Shared/_NewLayout.cshtml";
}
<h1>Details Page</h1>
Now, run the application and navigate to Home/Details. You should get the following output,
which means the Details view now uses the Layout, which is specified in the Details view
only.
166
Now, if you don’t want to use any layout or want to render a view without a layout, then you
need to set the Layout property to null. For example, if you don’t want to use a Layout in
Details View, you need to modify the Details.cshtml view as follows.
@{
ViewBag.Title = "Details Page";
Layout = null;
}
<h1>Details Page</h1>
Now, run the application and navigate to the Home/Details URL. You should see the output
without using any layout page.
How Do We Select a Layout Conditionally in the ViewStart file?
To conditionally select a layout in the _ViewStart.cshtml file in an ASP.NET Core MVC
application, you can use C# code to set the layout based on certain conditions. Here is a
step-by-step guide on how to do this:
• Identify the Condition: First, you need to determine the condition for
changing the layout. This could be based on the current controller, action, user
roles, or any custom logic.
• Implement the Conditional Logic: Inside the _ViewStart.cshtml file, you can
write C# code within @{ … } blocks. Use this capability to implement your
conditional logic when selecting the layout.
When you work with a Real-Time ASP.NET Core MVC application, you may have multiple
layout views. Let’s say you have two Layouts, such
as _NonAdminLayout and _AdminLayout. If you want to select the layout based on the
user role, i.e., if the user role is Admin, then use _AdminLayout; otherwise, use
the _NonAdminLayout. Then, you need to write the following conditional logic within
the _ViewStart.cshtml file, which will select the layout based on the logged-in user’s role.
@{
if (User.IsInRole("Admin"))
{
Layout = "_AdminLayout";
}
167
else
{
Layout = "_NonAdminLayout";
}
}
Here’s an example of selecting a layout based on the controller name. You can access route
data through the ViewContext.RouteData property. The controller name is stored in this route
data.
@{
var controllerName = ViewContext.RouteData.Values["controller"].ToString();
if (controllerName == "Home")
{
Layout = "~/Views/Shared/_HomeLayout.cshtml";
}
else if (controllerName == "Admin")
{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
else
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
namespace FirstCoreMVCApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
Modifying Home Controller:
Next, modify the Home Controller as shown below. As you can see, here we have created
two action methods. The Index Action Method displays all the student data, while the Details
Action Method takes the student ID as a parameter and returns that student information.
using FirstCoreMVCApplication.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace FirstCoreMVCApplication.Controllers
{
public class HomeController : Controller
169
{
public ViewResult Index()
{
List<Student> listStudents = new List<Student>()
{
new Student() { StudentId = 101, Name = "James", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 102, Name = "Smith", Branch = "ETC", Section = "B",
Gender = "Male" },
new Student() { StudentId = 103, Name = "David", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 104, Name = "Sara", Branch = "CSE", Section = "A", Gender
= "Female" },
new Student() { StudentId = 105, Name = "Pam", Branch = "ETC", Section = "B", Gender
= "Female" }
};
return View(listStudents);
}
public ViewResult Details(int Id)
{
var studentDetails = new Student() { StudentId = Id, Name = "James", Branch = "CSE",
Section = "A", Gender = "Male" };
return View(studentDetails);
}
}
}
Modifying the Index and Details view:
Index.cshtml:
@model List<FirstCoreMVCApplication.Models.Student>
@{
Layout = null;
}
<html>
170
<head>
<title>Index</title>
</head>
<body>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Branch</th>
<th>Section</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
@foreach (var student in Model)
{
<tr>
<td>
@student.StudentId
</td>
<td>
@student.Name
</td>
<td>
@student.Branch
</td>
<td>
@student.Section
</td>
<td>
@student.Gender
</td>
171
</tr>
}
</tbody>
</table>
</body>
</html>
Details.cshtml:
@model FirstCoreMVCApplication.Models.Student
@{
Layout = null;
}
<html>
<head>
<title>Student Detaills</title>
</head>
<body>
<div>
StudentId : @Model?.StudentId
</div>
<div>
Name : @Model?.Name
</div>
<div>
Branch : @Model?.Branch
</div>
<div>
Section : @Model?.Section
</div>
<div>
Gender : @Model?.Gender
</div>
</body>
</html>
172
In the above Index and Details view, we are using the @model directive to specify the model
for the view. If you notice, you can see in both views we have specified the fully qualified
name for the model, such as FirstCoreMVCApplication.Models.Student. Now, let us see
how to move the namespace to the ViewImports file so we can only specify the model name.
Creating ViewImports.cshtml file in ASP.NET Core MVC Application:
In general, _ViewImports.cshtml files are created within the Views or within the subfolder of
the Views folder. To create the _ViewImports.cshtml file, right-click on the Views folder and
then select the Add – New Item option from the context menu, which will open the “New Item”
window. From the New Item window, search for Razor, select the Razor View Import, and
click on the Add button as shown in the image below, which should create
the _ViewImport.cshtml within the Views folder.
Note: When creating the project using the ASP.NET Core Web Application using the Model-
View-Controller Project template, Visual Studio adds the _ViewImports.cshtml file with the
Views Folder by default. Once the _ViewImports.cshtml file is created, copy and paste the
following code.
@using FirstCoreMVCApplication.Models;
As we placed the above namespace in the ViewImports file, all the types present in the
above namespace are available to every view of our application. So now we don’t need to
type the Type’s fully qualified name. So, modify the Index and Details view as shown below.
173
As you can see in the above image, we are removing the namespace and only specifying the
model name. Run the application, and it should work as expected.
_ViewImports file Hierarchical Order in ASP.NET Core MVC:
Like the _ViewStart file, the _ViewImports file is hierarchical. It is also possible to pace the
_ViewImports in the subfolder of the Views folder. The following are the places where you
can place the _ViewImports file in ASP.NET Core MVC:
• Application Level: The root level of the application is the most general level
where a _ViewImports.cshtml file can be placed. Located in the Views folder,
directives placed here are globally available to all views throughout the
application. This is the highest level in the hierarchy.
• Area Level: If your application is structured using Areas to group related
functionalities, each area can have its own _ViewImports.cshtml file. This file
is located within the Areas/[AreaName]/Views directory. Directives here apply
to all views within the specified area, overriding or augmenting directives from
the application level.
• Controller Level: Within each area or the root Views directory, the controller-
specific _ViewImports.cshtml can be placed inside
the Views/[ControllerName] directory. This targets all views associated with
the specified controller, allowing for controller-specific namespaces or tag
helpers.
• View Level: The most specific level is directly within a specific view file. This
allows for more control over directives that apply only to a particular view.
Please have a look at the image below to better understand. Here, we have
one ViewImports file in the Views folder and another within the Home folder.
174
The settings specified in the _ViewImports file in the Home subfolder will overwrite the
settings specified in the _ViewImports file in the Views folder.
MVC Web Application named “PartialViewInMVC” using the Model View Controller Project
Template.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:16 / 03:1110 Sec
Creating Product Model:
Create a class file named Product.cs within the Models folder, then copy and paste the
following code. This simple class has a few properties to hold the Product information.
namespace PartialViewInMVC.Models
{
public class Product
{
public long ProductID { get; set; }
public string? Name { get; set; } = null!;
public string Category { get; set; } = null!;
public string Description { get; set; } = null!;
public decimal Price { get; set; }
}
}
The View for rendering Product Details in ASP.NET Core MVC View is like the one below.
176
This is just a simple Product class for demonstration purposes. What if we wanted to display
objects with twenty or even more properties? And what if we needed to display this
information on many pages in our application? Writing the same code repeatedly would be
time-consuming and error-prone, and maintenance becomes a headache; if we need to
modify anything, we must do it in all places. This is where Partial Views Come into the picture
in the ASP.NET MVC Application.
Creating Product Controller:
Add a new Controller named ProductController within the Controllers folder, and choose
the “MVC Controller – Empty” template. Once you Create the ProductController, copy and
paste the following code into it.
using Microsoft.AspNetCore.Mvc;
using PartialViewInMVC.Models;
namespace PartialViewInMVC.Controllers
{
public class ProductController : Controller
{
private List<Product> products = new List<Product>();
public ProductController()
{
products = new List<Product>()
{
new Product { ProductID =1, Name ="Product 1", Category = "Category 1", Description
="Description 1", Price = 10m},
new Product { ProductID =2, Name ="Product 2", Category = "Category 1", Description
="Description 2", Price = 20m},
new Product { ProductID =3, Name ="Product 3", Category = "Category 1", Description
="Description 3", Price = 30m},
new Product { ProductID =4, Name ="Product 4", Category = "Category 2", Description
="Description 4", Price = 40m},
new Product { ProductID =5, Name ="Product 5", Category = "Category 2", Description
="Description 5", Price = 50m},
new Product { ProductID =6, Name ="Product 6", Category = "Category 2", Description
="Description 6", Price = 50m}
};
}
public ActionResult Details(int Id)
177
{
var ProductDetails = products.FirstOrDefault(prd => prd.ProductID == Id);
return View(ProductDetails);
}
}
}
Next, add the Details.cshtml view within the Views => Product folder. Once you add the
view, copy and paste the following code.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
<tr>
178
<td>
@Model?.ProductID
</td>
<td>
@Model?.Name
</td>
<td>
@Model?.Category
</td>
<td>
@Model?.Description
</td>
<td>
@Model?.Price
</td>
</tr>
</table>
</div>
Now, run your application and navigate to Product/Details/1, and you should get the
following output.
When we need a section of a web page (both the Razor Syntax and HTML Markup) on
several different pages, we must create and use them as Partial Views.
How Do We Create a Partial View in ASP.NET Core MVC Application?
179
Partial views are similar to regular views, but they start with an underscore (_) in their file
name to indicate that they are meant to be partial. For example, _ProductDetails.cshtml.
• Create the Partial View File: In the Views/Shared directory of your
ASP.NET Core MVC project, create a new file and name it according to its
purpose, for example, _ProductDetails.cshtml. The underscore (_) prefix is a
convention to denote partial views but is not mandatory.
• Define the Model (if needed): At the top of your partial view file, define the
model it will use, if any, using the @model directive.
• Add Markup and Razor Code: Implement the HTML markup and Razor
syntax as needed to render the portion of the page the partial view is
responsible for.
So, right-click on the /Views/Shared folder, then select the Add -> View option from the
context menu. It will open the following window. Here, we need to select Razor View and
click the Add button, as shown in the image below.
Once you click on the Add button, it will open the following window: Here, please provide the
View name as _ProductDetails, check the Create as a partial view check box, and then
click on the Add button as shown in the image below.
180
Once you create the _ProductDetails.cshtml Partial View, open the view file, and copy and
paste the following code. Here, you can see we are using Product as the model and then
displaying Product information.
@model PartialViewInMVC.Models.Product
<tr>
<td>
@Model?.ProductID
</td>
<td>
@Model?.Name
</td>
<td>
@Model?.Category
</td>
<td>
@Model?.Description
</td>
<td>
181
@Model?.Price
</td>
</tr>
How to Use the Partial Views in ASP.NET Core MVC Application?
There are many methods available to render a partial view from our main view, and we are
going to discuss all those methods in detail in our next article. Now, let us understand the
syntax to render the Partial View from the Main view or child view:
• Using Html.Partial or Html.RenderPartial methods: These methods are
called within a view to render a partial view synchronously. Html.Partial
returns an IHtmlString that can be rendered in a view, while Html.RenderPartial
writes directly to the response stream, which can improve
performance. Example: @Html.Partial(“_ProductDetails”, model)
• Using Html.PartialAsync or Html.RenderPartialAsync methods: These
are the asynchronous counterparts of the above methods and are
recommended when the partial view is performing I/O
operations. Example: await Html.RenderPartialAsync(“_ProductDetails”,
model)
• Using Tag Helpers: ASP.NET Core also supports rendering partial views
using Tag Helpers, which can be more readable and easier to use, especially
for those familiar with HTML. Example: <partial name=”_ProductDetails”
model=”Model” />
So, let us render the partial view in this example using the partial helper method. To this
HTML Helper method, we need to Pass the name of the partial view as a parameter. As our
partial view, expecting the Product object, we need to pass the Product model as the second
parameter, such as @await Html.PartialAsync(“_ProductDetails”, Model). So, modify
the Details.cshtml View as follows.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
182
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
@await Html.PartialAsync("_ProductDetails", Model)
</table>
</div>
Now, run your application and see that everything is working as expected. But this time, you
can re-use this partial view wherever you want, and moreover, if you decide to change how
product details should be rendered, the only View you need to change is
the _ProductDetails.cshtml partial view. The above @Html.PartialAsync helper method
passed a Product object to the “_ProductDetails” partial view. The partial view was
dynamically rendered.
Now, let us see how we can use the same Partial View from another View. Let us first modify
the Product Controller as follows. Here, you can see we have added the Index action method,
which is going to render all the product details.
using Microsoft.AspNetCore.Mvc;
using PartialViewInMVC.Models;
namespace PartialViewInMVC.Controllers
183
{
public class ProductController : Controller
{
private List<Product> products = new List<Product>();
public ProductController()
{
products = new List<Product>()
{
new Product { ProductID =1, Name ="Product 1", Category = "Category 1", Description
="Description 1", Price = 10m},
new Product { ProductID =2, Name ="Product 2", Category = "Category 1", Description
="Description 2", Price = 20m},
new Product { ProductID =3, Name ="Product 3", Category = "Category 1", Description
="Description 3", Price = 30m},
new Product { ProductID =4, Name ="Product 4", Category = "Category 2", Description
="Description 4", Price = 40m},
new Product { ProductID =5, Name ="Product 5", Category = "Category 2", Description
="Description 5", Price = 50m},
new Product { ProductID =6, Name ="Product 6", Category = "Category 2", Description
="Description 6", Price = 50m}
};
}
public ActionResult Index()
{
return View(products);
}
public ActionResult Details(int Id)
{
var ProductDetails = products.FirstOrDefault(prd => prd.ProductID == Id);
return View(ProductDetails);
}
}
}
184
Next, add the Index.cshhtml view within the Views => Product folder. Once you add the
view, copy and paste the following code. You will get any data if you use the PartialAsync
within a for-each loop. So, here, instead of PartialAsync, we are using the Partial method.
@model IEnumerable<PartialViewInMVC.Models.Product>
@{
ViewData["Title"] = "Index";
}
<h4>Product List</h4>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
@foreach (var item in Model)
{
Html.Partial("_ProductDetails", item);
}
</table>
As you can see in the above code, each loop item calls the same partial view by passing the
product object, which will act as the model in the partial view. With the above changes in
place, run the application and navigate to the Product/Index action method, and you will see
the data as expected, as shown in the image below.
185
Microsoft does not recommend using HTML.Partial method. You might encounter application
deadlocks, in which case you will receive one warning message, as shown in the image
below.
It is saying that instead of Partial Method, please use Partial Tag helper. So, what is Tag
helper that we will discuss in our upcoming article? Now, let us use the Partial Tag helper to
render the Partial View in ASP.NET Core MVC Application.
The Partial Tag Helper achieves the same asynchronous rendering behavior as the
PartialAsync HTML Helper. So, modify the Index View of the Product Controller as follows.
The model attribute is assigned a Product instance for binding to the partial view.
@model IEnumerable<PartialViewInMVC.Models.Product>
186
@{
ViewData["Title"] = "Index";
}
<h4>Product List</h4>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
@foreach (var product in Model)
{
<partial name="_ProductDetails" model="product" />
}
</table>
new Product { ProductID =2, Name ="Product 2", Category = "Category 1", Description
="Description 2", Price = 20m},
new Product { ProductID =3, Name ="Product 3", Category = "Category 1", Description
="Description 3", Price = 30m},
new Product { ProductID =4, Name ="Product 4", Category = "Category 2", Description
="Description 4", Price = 40m},
new Product { ProductID =5, Name ="Product 5", Category = "Category 2", Description
="Description 5", Price = 50m},
new Product { ProductID =6, Name ="Product 6", Category = "Category 2", Description
="Description 6", Price = 50m}
};
}
public ActionResult Index()
{
return View(products);
}
public ActionResult Details(int Id)
{
var ProductDetails = products.FirstOrDefault(prd => prd.ProductID == Id);
return View(ProductDetails);
}
}
}
Next, modify the _ProductDetails.cshtml Partial View file as follows:
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:26 / 03:1110 Sec
@model PartialViewInMVC.Models.Product
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
189
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
<tr>
<td>
@Model?.ProductID
</td>
<td>
@Model?.Name
</td>
<td>
@Model?.Category
</td>
<td>
@Model?.Description
</td>
<td>
@Model?.Price
</td>
</tr>
</table>
Render a Partial view using @Html.Partial() Method in ASP.NET Core
MVC:
190
The Html.Partial() method synchronously returns an IHtmlContent that represents the HTML
content generated by the specified partial view. Since it’s synchronous, it can potentially
block the thread if the operation takes a long time.
The Html.Partial() is an HTML helper method available in
the Microsoft.AspNetCore.Mvc.Rendering namespace. Four overloaded versions of the
Partial method are available, as shown in the image below.
Parameters:
• htmlHelper: The HTML helper instance that this method extends
• partialViewName: The name of the partial view to render
• viewData: The view data dictionary for the partial view.
• model: The model for the partial view.
Returns: The partial view that is rendered as an HTML-encoded string.
To render a partial view using @Html.Partial() html helper, please modify
the Details.cshtml view of the Product controller as shown below. Here, _ProductDetails is
the name of the partial view file, and Model is the model object.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<p>Rendering the Result of Partial View</p>
@Html.Partial("_ProductDetails", Model)
<br/>
<p>Storing the Result of Partial View into a variable</p>
@{
var result = Html.Partial("_ProductDetails", Model);
}
<span>@result</span>
</div>
191
To render a partial view using @Html.PartialAsync() html helper, please modify the
Details.cshtml file of the Product controller as shown below. Here, _ProductDetails is the
name of the partial view file, and Model is the model object. Here, we must use the await
keyword as this method works asynchronously.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<p>Rendering the Result of Partial View</p>
@await Html.PartialAsync("_ProductDetails", Model)
<br/>
<p>Storing the Result of Partial View into a variable</p>
@{
var result = await Html.PartialAsync("_ProductDetails", Model);
}
<span>@result</span>
</div>
Render a Partial view using @Html.RenderPartial() Method in ASP.NET
Core MVC:
The Html.RenderPartial synchronously renders the specified partial view to the response
stream. This method does not return a value; instead, it writes the rendered HTML directly to
192
the response’s output stream. This can be more efficient than HTML.Partial in terms of
memory usage since it doesn’t need to store the rendered HTML in an intermediary
IHtmlContent object before it’s written to the response.
The @Html.RenderPartial is also an HTML helper method for rendering a partial view. It is
available in the Microsoft.AspNetCore.Mvc.Rendering namespace. There are 4 overloaded
versions of the RenderPartial method available, as shown in the image below. You can use
any one of them as per your requirements.
Parameters:
• htmlHelper: The HTML helper instance that this method extends
• partialViewName: The name of the partial view.
• viewData: The view data for the partial view.
• model: The model for the partial view.
To render a partial view using @Html.RenderPartial() HTML helper, please modify
the Details.cshtml view of the Product controller as shown below. Here, _ProductDetails is
the name of the partial view file, and Model is the model object. This method works
synchronously.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<p>Rendering the Result of Partial View</p>
@{
Html.RenderPartial("_ProductDetails", Model);
}
</div>
Render a Partial view using @Html.RenderPartialAsync() Method in
ASP.NET Core MVC:
193
To render a partial view using @Html.RenderPartialAsync() HTML helper, please modify the
Details.cshtml file of the Product controller as shown below. Here, _ProductDetails is the
name of the partial view file, and Model is the model object. Here, we must use the await
keyword as this method works asynchronously.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<p>Rendering the Result of Partial View</p>
@{
await Html.RenderPartialAsync("_ProductDetails", Model);
}
</div>
Rending Partial View using Partial Tag Helper in ASP.NET Core MVC
The Partial Tag Helper, introduced in ASP.NET Core, is used within a view to render a partial
view. It uses a more concise syntax compared to the Html.* methods and supports
asynchronous rendering by default. The syntax looks like <partial name=”_PartialViewName”
/>, making it more readable and consistent with other tag helpers in ASP.NET Core. This
approach is often recommended for its simplicity and modern syntax. Important features of
Partial tag helper –
• Easy to use
• HTML like syntax
• The partial tag works in async mode
• Newly introduced tag helper in ASP.NET Core
To render a partial view using the partial tag helper, please modify the Details.cshtml file of
the Product controller as shown below.
194
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
}
<div>
<h4>Product Details</h4>
<p>Rendering the Result of Partial View</p>
<partial name="_ProductDetails" model="Model" />
</div>
Let’s discuss the details of this partial tag helper –
• Tag name: The name of the tag is partial. <partial /> is a self-closing tag helper.
• Partial view name: We can write the name of the partial view using the name
attribute of the partial tag.
• Pass data (Model) to the partial view: We can pass the model to the partial
view using the model attribute of the partial tag.
Partial View with ViewData in ASP.NET Core MVC:
Now, let us understand how to create a partial view that will accept a model object as well as
a ViewData. So, modify the _ProductDetails.cshtml partial view as follows. As you can see,
we are using the Product model as well as a ViewData for displaying the header.
@model PartialViewInMVC.Models.Product
@{
var heading = ViewData["Header"];
}
<h2>@heading</h2>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
195
Description
</th>
<th>
Price
</th>
</tr>
<tr>
<td>
@Model?.ProductID
</td>
<td>
@Model?.Name
</td>
<td>
@Model?.Category
</td>
<td>
@Model?.Description
</td>
<td>
@Model?.Price
</td>
</tr>
</table>
Next, modify the Details.cshtml view of the product controller is as follows. Here, I show how
to call the partial view using ViewData with all five approaches.
@model PartialViewInMVC.Models.Product
@{
ViewData["Title"] = "Details";
ViewData["Header"] = "Product Details";
}
<div>
<p>Using Tag Helper</p>
196
•
Performance: Generally, @Html.RenderPartial is more efficient, especially
for larger partial views, because it avoids the overhead of generating and then
writing an IHtmlString to the output.
Note: The same differences are there between @Html.PartialAsync and
@Html.RenderPartialAsync. The only difference is that @Html.PartialAsync and
@Html.RenderPartialAsync work asynchronously, whereas @Html.Partial and
@Html.RenderPartial work synchronously.
Choosing the Right Method
• For Synchronous Operations: If the partial view rendering is CPU-bound
and expected to complete quickly, Html.Partial or Html.RenderPartial might be
suitable. However, in most cases, it’s better to default to asynchronous
methods to avoid blocking the thread.
• For Asynchronous Operations: When the partial view involves I/O-bound
operations, prefer Html.PartialAsync, Html.RenderPartialAsync, or the Partial
Tag Helper. These methods allow the thread to be released back to the thread
pool to handle other requests while waiting for the I/O operations to complete.
• For Cleaner Syntax and Consistency: The Partial Tag Helper is often
preferred for its cleaner syntax and consistency with other tag helpers in
ASP.NET Core, making your views more readable and maintainable.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:16 / 03:1110 Sec
Server-side file (.cs): This file can be created anywhere in the project. But we generally
create a new folder (with the name Components, ViewComponents, or any other name as
per your choice) at the root level of the project and put all the view components in this new
folder.
Client-side file (.cshtml): The client-side file of a view component must be placed at a
specific location.
• Location 1: If we want to call the view component from the controller’s action
method, then we need to add the view component client-side file at the
198
}
ProductRepository File:
Create a Class file named ProductRepository.cs within the Models folder, and then copy
and paste the following code. The code for getting the top products from the database is
written in the ProductRepository.cs file. You will get the data from the database in real time,
but here, we have hard-coded it.
namespace ViewComponentInMVC.Models
new Product { ProductID =1, Name ="Product 1", Category = "Category 1", Description
="Description 1", Price = 10m},
new Product { ProductID =2, Name ="Product 2", Category = "Category 1", Description
="Description 2", Price = 20m},
new Product { ProductID =3, Name ="Product 3", Category = "Category 1", Description
="Description 3", Price = 30m},
new Product { ProductID =4, Name ="Product 4", Category = "Category 2", Description
="Description 4", Price = 40m},
200
new Product { ProductID =5, Name ="Product 5", Category = "Category 2", Description
="Description 5", Price = 50m},
new Product { ProductID =6, Name ="Product 6", Category = "Category 2", Description
="Description 6", Price = 50m}
};
//We are Delaying the Execution for 1 Seconds to get the Data from the database
await Task.Delay(TimeSpan.FromSeconds(1));
return products.Take(count).ToList();
}
View Component Server-Side File in ASP.NET Core MVC:
Now, we need to create the view component server-side file. In the project, we can add the
server-side file at any location (let’s say /ViewComponents folder). So, in the project root
directory, create a folder with the name ViewComponents. Suppose the name of the view
component server-side file is TopProducts; then we must add a suffix ViewComponent to
its name. Hence, the final name of the view component server-side file will
be TopProductsViewComponent.
We typically create a class that inherits from ViewComponent. It contains the logic to generate
the content. This class can return a view (HTML) using the View method, similar to how
actions in controllers work. The Invoke Method is the entry point for the View Component,
which can be named Invoke or InvokeAsync for asynchronous operations. This method
contains the logic to generate the data and optionally select a view to render it.
So, create a class file named TopProductsViewComponent.cs within
the ViewComponents folder and copy and paste the following code. The code is self-
explained, so please read the comment line for a better understanding.
using Microsoft.AspNetCore.Mvc;
using ViewComponentInMVC.Models;
namespace ViewComponentInMVC.ViewComponents
return View(products);
//{
// return View(products);
//}
}
In the above example:
• TopProductsViewComponent: The TopProductsViewComponent is
inherited from the ViewComponent class. This inheritance makes
TopProductsViewComponent a View Component, providing it with the
capabilities to execute logic and return a view for rendering.
• InvokeAsync Method: The InvokeAsync method is the entry point for the
View Component and can be called when the component is invoked from a
Razor view. The method is asynchronous, allowing for non-blocking I/O
operations, such as database calls.
• return View(products);: Returns a view for rendering, passing items as the
model. The View method is a helper method inherited from ViewComponent,
202
and it looks for a Razor view that matches the View Component’s name. The
items model will be passed to the view, which can then be used to render
HTML.
View Component Client-Side File in ASP.NET Core MVC:
We are using the ASP.NET Core MVC Application and want to invoke the View Component
from a view file. Hence, we need to place the client-side file at the following
location /Views/Shared/Components/{ViewComponentName}/{ViewName}.cshtml. In
our example, the View Component Name is TopProducts, and the view name is going to
be Default.cshtml. So, we need to create the View in the following location.
/Views/Shared/Components/TopProducts/Default.cshtml
Once you create the Default.cshtml view file, your Views folder should look as shown below.
Now, open Default.cshtml view file and then copy and paste the following code into it.
@model IEnumerable<Product>
<div class="row">
<div>
<h4>Product Details</h4>
<table class="table">
<tr>
<th>
ProductID
</th>
<th>
203
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
<tr>
<td>
@product?.ProductID
</td>
<td>
@product?.Name
</td>
<td>
@product?.Category
</td>
204
<td>
@product?.Description
</td>
<td>
@product?.Price
</td>
</tr>
</table>
</div>
</div>
With this, our view component is completed and ready to use.
Invoking the View Component in ASP.NET Core MVC:
Now, we need to invoke it from another view file. So, modify the Index.cshtml file of Home
Controller as follows. Here, TopProducts is the name of the View Component, and
the count is the parameter with a value of 3. You can assign any value to the count
parameter. If you check the View Component CS class file, you will see the InvokeAsync or
Invoke method taking one integer parameter named count, and here, we pass a value 3 to
that count parameter.
@{
<div class="text-center">
</div>
With the above changes, run the application, and you should get the following output.
205
@using ViewComponentInMVC.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, ViewComponentInMVC
@addTagHelper *, ViewComponentInMVC.TagHelpers
Now, if you want to invoke the View Component using Tag Helper, then modify
the Index.cshtml file of the Home controller as follows:
@{
<div class="text-center">
<vc:top-products count="3"></vc:top-products>
</div>
View Components Real-Time Examples in ASP.NET Core MVC:
To avoid code duplication in ASP.NET Core MVC Web Applications, the View Components
can be used in various areas such as the Navigation Menus, Login Panel, Billing and Shipping
Address, Shopping Cart, etc. View components can be used to create the following features:
• Login Panel.
• Dynamic Navigation Menu (Based on role etc.).
• Get some related data for a page. (Like Related posts, Related books).
• Shopping Cart.
• Shipping and Billing Address.
• Any content visible on the side of the Web Page, etc.
View Component vs. Partial View in ASP.NET Core MVC
In ASP.NET Core MVC, View Components and Partial Views are used to create reusable
pieces of Web UI, allowing developers to avoid duplicating markup across different views.
However, they serve different purposes and come with their own features, making them
suitable for different scenarios.
View Component in ASP.NET Core MVC
View Components are intended for more complex scenarios where you need to execute some
logic before rendering the HTML. They are a combination of a C# class that handles the logic
and a Razor view that generates the HTML markup. View Components are not part of the
MVC request life cycle, which means they cannot directly respond to HTTP requests. Instead,
they are invoked from within a view and can be used to render a portion of a page’s response
with its own logic.
View Components are intended to be used in situations where you need a component that
can perform actions, not just display static HTML. For example, a View Component might
display a dynamically generated menu, a shopping cart summary, or widgets that display
complex data.
Partial View in ASP.NET Core MVC
Partial Views, on the other hand, are more straightforward. They are essentially segments of
Razor markup that can be rendered within other views. Unlike View Components, Partial
Views do not have their own logic. They depend on the data provided to them by the view
that renders them, typically through model binding or ViewData/ViewBag.
Partial views are best for static or markup-heavy fragments without additional processing or
data fetching. They are also best for static content reused in multiple places, such as headers,
footers, or reusable forms.
Key Differences Between View Component and Partial View ASP.NET
Core MVC
• Complexity and Functionality: View Components are more complex and
can encapsulate both logic and rendering, making them suitable for
components that require server-side processing. Partial Views are better for
207
scenarios where you need to refactor or reuse the visual parts of views without
additional logic, i.e., ideal for static content.
• Invocation: View Components are invoked from views or layouts using C#
code, can accept parameters, and can be considered more like mini-controllers
with their own logic. On the other hand, Partial Views are typically invoked with
Html.Partial or Html.RenderPartial methods in Razor syntax rely on the parent
view’s model or ViewData for data.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:14 / 03:1110 Sec
What is Razor Markup?
Razor Markup refers to the syntax used in Razor view templates in ASP.NET web
applications to combine server-side code with HTML markup. Razor Markup allows
developers to embed C# code directly within HTML, making generating dynamic and data-
driven content for web pages easier. The Razor Markup syntax is designed to be concise,
readable, and intuitive, enabling seamless integration of code and markup.
The Controller in ASP.NET Core MVC invokes the View by passing the data to render. The
Views must be able to process the data and generate a response. This is done using the
Razor markup, which allows us to use C# code in an HTML file. The Razor View Engine
processes these markups to generate the HTML.
Files containing Razor markup generally have a .cshtml file extension. Razor syntax is
shorter, simpler, and easy to learn, as it uses C# or Visual Basic. Visual Studio IntelliSense
support also helps with Razor syntax.
Example to Understand Razor Syntax in ASP.NET Core MVC:
First, create a new ASP.NET Core Web Application using the Model-View-Controller Project
template with the name RazorSyntaxDemo. Then, create a class file with the
name Product.cs within the Models folder and copy and paste the following code.
namespace RazorSyntaxDemo.Models
{
public class Product
{
public long ProductID { get; set; }
public string? Name { get; set; } = null!;
public string Category { get; set; } = null!;
public string Description { get; set; } = null!;
public decimal Price { get; set; }
209
}
}
Razor Syntax in ASP.NET Core MVC:
The Razor uses the @ symbol to switch from HTML markup to the C# code. The following
are the two ways by which you can achieve the transitions.
1. Using Razor code expressions
2. Using Razor code blocks.
These expressions are evaluated by the Razor View Engine and written to the response.
Razor Code Block Syntax in ASP.NET Core MVC:
The Razor code blocks start with the @ symbol followed by curly braces. You can use code
blocks anywhere in the markup. A Razor code block can be used to manipulate a model,
declare variables, set local properties on a view, etc. However, it would be best if you did not
use it for business logic.
Now, open the index.cshtml file of Home Controller and copy and paste the following code
into it.
<h3>Code Block</h3>
@{
var greeting = "Welcome to ASP.NET Core MVC!";
var weekDay = DateTime.Now.DayOfWeek;
ViewData["Title"] = "Home Page";
}
@{
var product = new RazorSyntaxDemo.Models.Product()
{
ProductID = 1000,
Name = "Laptop",
Description= "Its a Gaming Laptop",
Category = "Electronics",
Price = 10000
};
}
First, we have created a Razor code block beginning with a @ symbol and { } curly brackets.
Inside the Curly brackets, we have regular C# code, which declares greeting and weekDay
Variables as well as a ViewData to hold the Title property. The Second Razor Code block
creates a product variable, which is a new instance of the Product model class.
Razor Code Expression Syntax in ASP.NET Core MVC
The Razor Code expressions start with @ and are followed by C# code. The Code expression
can be either Implicit or Explicit.
210
}
<h3>Code Expression</h3>
<p>@(greeting)</p>
<p>@(DateTime.Now)</p>
<p>Today is : @(weekDay) thank you </p>
<p>Name : @(product.Name)</p>
<p>Description : @(product.Description)</p>
<p>Price : @(product.Price)</p>
Now, run the application, and you should see the following output.
Using Directive
The @using directive works similarly to the C# using directive and allows you to import
namespaces and the RazorSyntaxDemo.Models can be imported as shown below. Here, you
don’t need to need the statement with a semicolon.
@using RazorSyntaxDemo.Models
And then, we can use var product = new Product() instead of var product = new
RazorSyntaxDemo.Models.Product() as follows:
@using RazorSyntaxDemo.Models
<h3>Code Block</h3>
@{
var greeting = "Welcome to ASP.NET Core MVC!";
var weekDay = DateTime.Now.DayOfWeek;
ViewData["Title"] = "Home Page";
}
@{
var product = new Product()
{
ProductID = 1000,
Name = "Laptop",
Description= "Its a Gaming Laptop",
214
Category = "Electronics",
Price = 10000
};
}
Variable Declaration using Razor Syntax in ASP.NET Core MVC
The Variables are declared using the var keyword or using the C# data type. The int, float,
decimal, bool, DateTime & string keywords can be used to store strings, numbers, dates, etc.
The variables are inserted directly into a page using @.
<h3>Variables </h3>
<!-- Storing a string -->
@{
string message = "Welcome to ASP.NET Core MVC";
}
<!—Storing date and integer-->
@{
DateTime date = DateTime.Now;
int Number = 100;
}
<p>@message</p>
<p> The current date is @date</p>
<p>Numbers : @Number</p>
Now, run the application, and you should see the following output.
215
Strings are enclosed in double quotation marks. To use a double quotation mark inside the
string, use a verbatim string literal. The verbatim string is prefixed with the @ symbol and
repeats the quotation mark.
@{
var helloWorld = @"Hello ""World""";
}
<p>@helloWorld</p>
Similarly, backslash characters can be printed using the same technique.
@{
var Path = @"C:\Windows\";
}
<p>The path is: @Path</p>
You can print @ in HTML by repeating (Escape) the @ symbol as shown below.
@{
var symbol = "You can print @ in html";
}
<p>The @@symbol is: @symbol</p>
So, modify the Index view as follows:
@{
var helloWorld = @"Hello ""World""";
}
<p>@helloWorld</p>
@{
var Path = @"C:\Windows\";
}
<p>The path is: @Path</p>
@{
var symbol = "You can print @ in html";
}
<p>The @@symbol is: @symbol</p>
Now, run the application, and you should see the following output.
216
Comments
Use @* *@ to place comments
@*This is comment*@
HTML Elements inside the code block
The Razor Engine Correctly Identifies any HTML Elements inside the Razor code block, as
shown below.
@{
<p>Hello from the Code block</p>
}
Single line text
You can output the literal values without the HTML element by prefixing it with @: and @:
used to define the single line of literal values.
@{
@:Hello from the Code block
}
Multiline text
For the multiline text use the <text> </text> element
@{
<text>
Multiline text 1
Multiline text 2
Multiline text 3
</text>
}
217
Conditional Statements
The Razor engine is able to process conditional statements like if and Switch statements.
If and Else Conditions
If Condition is used to render a section based on a condition as shown below.
@{
int value = 200;
}
@if (value > 100)
{
<p>Value is greater than 100</p>
}
else
{
<p>Value is less than 100</p>
}
Or you can use the following code.
@{
var value = 200;
if (value > 100)
{
<p>The value is greater than 100</p>
}
else
{
<p>This value is less than 100</p>
}
}
Switch Statements in Razor View
A switch statement can insert a section into HTML based on a number of conditions.
@{
var value = 200;
}
@switch (value)
{
218
case 0:
@: value is Zero
break;
case 100:
<p>Value is 100 </p>
break;
case 200:
<p>Value is @value </p>
break;
case 300:
<text>Value is 300</text>
break;
default:
<p>Invalid Value </p>
break;
}
Loops
For loop
The loops are used to repeat a code block for,
@for (int i = 0; i < 5; i++)
{
<span> @i </span>
}
Foreach loop
The best use case of a for-each loop is to loop through a collection object and display the
result inside a table.
@using RazorSyntaxDemo.Models
@{
var productList = new List<Product>()
{
new Product() { ProductID = 1001, Name = "Laptop", Price = 1000 },
new Product() { ProductID = 1002, Name = "Desktop", Price = 2000 },
new Product() { ProductID = 1002, Name = "Mobile", Price = 3000 }
};
219
}
<table>
<thead>
<tr><td>ProductID</td><td>Name</td><td>Price</td></tr>
</thead>
@foreach (Product product in productList)
{
<tr>
<td>@product.ProductID</td>
<td>@product.Name</td>
<td>@product.Price</td>
</tr>
}
</table>
While loop:
<h3>While loop</h3>
@{
var r = 0;
while (r < 5)
{
r += 1;
<span> @r</span>
}
}
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:12 / 03:1110 Sec
How to Check and Upgrade the Version in Visual Studio?
In order to check the Visual Studio Version, you need to follow the below steps.
Click on the “Help” menu and then select the “About Microsoft Visual Studio” option from
the context menu. This will open the “About Microsoft Visual Studio” Window, which shows
the version number of Visual Studio in the image below. I have installed Visual Studio 2022
on my machine with Version 17.6.4.
221
Once it is successfully installed, then you will find two things. One is the libman.json file, and
the second one is the required bootstrap files. Please have a look at the following image.
As you can see in the above code, we have an entry for the Bootstrap library that we just
installed using Libman. It is also possible to install client-side libraries like Bootstrap and
jQuery by editing the above manifest file.
How to Clean Client-Side Libraries using LibMan in ASP.NET Core?
If you want to clean the library files created using the Library Manager, right-click on the
libman.json file and select the “Clean Client-Side Libraries” option from the context menu,
as shown in the below image.
Once you click on the “Clean Client-Side Libraries” option, then it will delete all the library
files from the respective destination folder. The point that you need to remember is that it will
only delete the files from the folder but not in the libman.json file. Please look at the following
image and see the Twitter-bootstrap folder; its files are deleted, but the libman.json file is still
there.
224
Once you click on the “Restore Client-Side Libraries” option, it will again download and
install the required library files into the specified destination folder, as shown in the image
below.
225
"library": "[email protected]",
"destination": "wwwroot/lib/jqueryui/"
}
]
}
Then right-click on the libman.json file and select the “Restore Client-Side Libraries” option
from the context menu, and it should add the respective jQuery library, as shown in the image
below.
Another approach to uninstall a client-side library is to remove the entry from the libman.json
file, and upon saving the file, the respective client-side libraries are uninstalled from the
respective folder location. For example, if we modify the libman.json file as shown below, you
will immediately see the respective library being deleted from the wwwroot project folder.
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "[email protected]",
"destination": "wwwroot/lib/twitter-bootstrap/"
}
]
}
Now, you can check the lib folder, which is inside the wwwroot folder, and you should see
that the JqueryUI folder was deleted, as shown in the below image.
228
create the Project, add Bootstrap to your application using the Library Manager (Libman). Our
previous article discussed how to install BootStrap into ASP.NET Core MVC Application. So,
you must follow the steps below to install Bootstrap on your application.
1. Right-click on the “Project Name” in the Solution Explorer and then
select Add > Client-Side Library, which will open the “Add Client-Side
Library” Window.
2. Leave the default provider as it is, which “cdnjs” is in this case. The other
providers are filesystem, jsdelivr, and unpkg.
3. In the “Library” text box, type “twitter-bootstrap“. You can also get
intelligence support once you start typing. Once you select the matching entry,
then it tries to install the latest version of Bootstrap. However, if you want, you
can manually type the version number. Here, we are installing the latest version
of Bootstrap, i.e. ([email protected]).
4. There are two radio buttons to select whether you to include “All library files”
or “Choose Specific files“. If you select the “All library files” radio button, all
the files will be downloaded. On the other hand, if you select the Choose
Specific Files radio button, you need to check the selected checkboxes as per
your requirement. Here, I am selecting the “All library files” radio button.
5. In the “Target Location” text box, specify the folder location where you want
the library files to be installed. By default, the static files are only served from
the wwwroot folder. I am going with the default location, i.e.,
“wwwroot/lib/twitter-bootstrap/”.
6. Finally, click on the “Install” button, as shown in the image below.
230
Once it is successfully installed, then you will find two things. One is the libman.json file, and
the second one is the required bootstrap files. Please have a look at the following image.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:17 / 03:1110 Sec
Once you add the MyCustomStyleSheet.css file, then your wwwroot folder should look as
shown below.
Note: All the custom style sheets for our application need to be placed within
the MyCustomStyleSheet.css file. So, open the MyCustomStyleSheet.css file and copy and
232
paste the following code into it. We are going to use the custom .btn style sheet in our
application.
.btn {
width: 80px;
}
How to Use Bootstrap in ASP.NET Core MVC Application?
In order to use Bootstrap, first, you need to include a reference to the bootstrap.css file. You
can add the reference on each individual view. But as we are going to use the Layout file,
we will add a reference to the bootstrap.css file in the _Layout.css file. Along
with bootstrap.css, we are also including a reference to our custom style sheet,
i.e., MyCustomStyleSheet.css.
Modifying _Layout.cshtm file:
Please modify the Layout.cshtml file, which is present in the shared folder, as shown below.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/css/MyCustomStyleSheet.css" rel="stylesheet" />
</head>
<body>
<div class="container">
@RenderBody()
</div>
</body>
</html>
As you can see in the HTML code, we have included references for both bootstrap.css as
well as MyCustomStyleSheet.css files. Here, we also use the bootstrap container class to
position the elements on the page.
Creating Models:
Within the Models folder, add a class file with the name Student.cs and then copy and paste
the following code into it. As you can see, this is a very simple Student Model having only five
properties holding the Student Id, Name, Branch, Section, and Gender.
namespace FirstCoreMVCApplication.Models
{
public class Student
233
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
public string? Section { get; set; }
public string? Gender { get; set; }
}
}
Modifying the Home Controller:
Next, modify the Home Controller as shown below. As you can see in the below code, we
have created two action methods. The Index action method returns a list of students to the
view, whereas the Details action method takes the student id as a parameter and then returns
that student information to the view. Here, we have hard-coded the data, but in real-time, you
will get the data from a database.
using FirstCoreMVCApplication.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace FirstCoreMVCApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
//Create a List of Students
//In Real-Time, you will get the data from the database
List<Student> listStudents = new List<Student>()
{
new Student() { StudentId = 101, Name = "James", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 102, Name = "Smith", Branch = "ETC", Section = "B",
Gender = "Male" },
new Student() { StudentId = 103, Name = "David", Branch = "CSE", Section = "A",
Gender = "Male" },
new Student() { StudentId = 104, Name = "Sara", Branch = "CSE", Section = "A", Gender
= "Female" },
234
new Student() { StudentId = 105, Name = "Pam", Branch = "ETC", Section = "B", Gender
= "Female" }
};
//Pass the Student List to the View to make the view as a Strongly Typed View
return View(listStudents);
}
public ViewResult Details(int Id)
{
//Here, we have hard coded the student details
//In Real-Time, you will get the student information from the database
Student studentDetails = new Student() { StudentId = Id, Name = "James", Branch =
"CSE", Section = "A", Gender = "Male" };
//Pass the Student model to the View to make the view as a Strongly Typed View
return View(studentDetails);
}
}
}
Main Method of the Program class:
Next, modify the Main method of the Program class as shown below. The point that you need
to remember is to serve Bootstrap, we need to add the static files middle layer before the
MVC middle layer in the request processing pipeline. Further, you can notice we are making
the Home Controller Index action method the default route for our application.
namespace FirstCoreMVCApplication
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add MVC services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
235
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
//Adding Static Files Middleware to Serve the Static Files
//This Should be added before the MVC Middleware
app.UseStaticFiles();
//This should be included we want to use End Point Routing
app.UseRouting();
app.UseAuthorization();
//Adding MVC Middleware to the Request processing Pipeline
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
}
}
}
Modifying the Index View of the Home Controller:
Please modify the Index view, which is present inside the Home Controller, as shown below.
As you can see in the below HTML, we are using Bootstrap in-built classes like class=”table-
responsive”, class=”table”, class=”text-center” and class=”btn btn-primary”. Here, we are not
going to explain the Bootstrap class. Instead, I am only going to show you how to use
Bootstrap in ASP.NET Core MVC Application.
@model List<FirstCoreMVCApplication.Models.Student>
@{
ViewBag.Title = "Student List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="table-responsive">
<table class="table">
<thead>
236
<tr>
<th>ID</th>
<th>Name</th>
<th>View</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach (var student in Model)
{
<tr>
<td>@student.StudentId</td>
<td>@student.Name</td>
<td class="text-center"><a href="#" class="btn btn-primary">View</a></td>
<td class="text-center"><a href="#" class="btn btn-primary">Edit</a></td>
<td class="text-center"><a href="#" class="btn btn-danger">Delete</a></td>
</tr>
}
</tbody>
</table>
</div>
Creating Details View inside the Home Folder:
Next, create a view with the name Details.cshtml and copy and paste the following code. As
you can see in the below HTML, we are using Bootstrap in-built classes such as class=”row
justify-content-center m-3″, class=”col-sm-8″, lass=”card”, class=”card-header text-center”,
class=”card-body text-center”, lass=”card-footer text-center”, class=”btn btn-primary”, etc.
@model FirstCoreMVCApplication.Models.Student
@{
ViewBag.Title = "Student Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="row justify-content-center m-3">
<div class="col-sm-8">
237
<div class="card">
<div class="card-header text-center">
<h1>@Model?.Name</h1>
</div>
<div class="card-body text-center">
<h4>Studnet ID : @Model?.StudentId</h4>
<h4>Branch : @Model?.Branch</h4>
<h4>Section : @Model?.Section</h4>
<h4>Gender : @Model?.Gender</h4>
</div>
<div class="card-footer text-center">
<a href="#" class="btn btn-primary">Back</a>
<a href="#" class="btn btn-primary">Edit</a>
<a href="#" class="btn btn-danger">Delete</a>
</div>
</div>
</div>
</div>
That’s it. Save the changes, run the application, and then visit the Home/Index or the root
URL, and you should get the following output.
encapsulated in objects known as action results. So, in ASP.NET Core MVC, action results
represent the various types of responses that a controller action can send back to the client.
Action Result is the Return Type of an Action Method in the ASP.NET Core MVC Application.
The Action Result is an abstract class. It is the base class for all types that an action method
returns. As you can see in the diagram below, View, Partial View, Redirect, Json, Content,
File, RedirectToAction, etc., are derived from the abstract Action Result class, and these
types can also be used as the return type of an action method.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
The constructor is used to initialize a new instance of the ActionResult class. It also has the
following two methods.
• ExecuteResult(ActionContext context): This method executes the action
method’s result operation synchronously. ASP.NET Core MVC Framework
calls this method to process the action method’s result. The context is the
240
object in which the result is executed. The context includes information about
the executed action, such as Controller, HTTP Content, request context, and
route data.
• ExecuteResultAsync(ActionContext context): This method executes the
action method’s result operation asynchronously. ASP.NET Core MVC
Framework calls this method to process an action method’s result.
Why is ActionResult an Abstract Class in ASP.NET Core MVC?
This is because different controller action methods can return different types of results
according to business needs, and the ASP.NET Core MVC Framework handles them
properly. If you mention an action method’s return type as ActionResult, then the action
method can return any type derived from the ActionResult abstract class.
Types of Action Results in ASP.NET Core MVC:
Action results in ASP.NET Core MVC can be categorized into different groups based on their
functionality and the type of response they generate.
View Results:
View Results in ASP.NET Core MVC are action results used to render and return HTML views
to the client’s browser. They generate the HTML content the user sees in their web browser.
View results allow you to combine dynamic data with HTML templates and create dynamic
web pages. There are two main types of View Results in ASP.NET Core MVC:
• ViewResult: The ViewResult in ASP.NET Core MVC renders a view as a
web page. It’s typically used when the action needs to display HTML content.
You return this by calling View() from your controller action.
• PartialViewResult: The PartialViewResult in ASP.NET Core MVC is
similar to ViewResult, but it renders a partial view instead of a full page. This is
useful in scenarios like updating a portion of the webpage with AJAX.
Content Results:
Content Results in ASP.NET Core MVC are action results that allow us to return raw content
directly to the client’s browser as a response. This raw content can be in various formats,
such as Plain Text, HTML, JSON, XML, or any other format, or even downloadable files like
CSV or XML. There are three main types of Content Results in ASP.NET Core MVC:
• ContentResult: The ContentResult in ASP.NET Core MVC returns a
specific content type to the response. It could be a string, HTML, JSON, or
plain text. Use the Content() method to specify the content and the content
type.
you need to perform a redirection, such as after a form submission or when handling
authentication. There are three main types of Redirect Results in ASP.NET Core MVC:
• RedirectResult: Redirects the client to another URL. It is useful in scenarios
where you want to redirect the user to an external URL. Use Redirect() for this
purpose.
Advantages:
• You can easily switch between different types of action results based on
client preferences or conditions.
• Easily handle multiple response types for the same action method.
Using Specific Derived Types:
With this approach, you explicitly define the return type of your action method as a specific
derived type like ViewResult, JsonResult, RedirectResult, etc. This approach can provide
more clarity and improve readability by making it explicit what type of response the action
method will produce. In the example below, the action method will return one type of result,
i.e., JsonResult, so it is advisable to use JsonResult as the action method’s return type.
• By specifying the action method return type as IActionResult, you can return
any type of action result that implements the interface, such as ViewResult,
JsonResult, FileResult, etc. This is useful when the action method needs to
return different types of results depending on the situation.
• It abstracts the actual type of result being returned, which is ideal for cases
where the details of the response are not important or should be hidden for the
sake of clean architecture.
ActionResult:
The ActionResult is an abstract class that implements the IActionResult interface.
ActionResult<T> is a generic subclass allowing more specific type control over the returned
data. Using ActionResult or ActionResult<T> as the return type of a controller action method
provides the following advantages:
• ActionResult<T> enhances type safety by allowing you to specify the type of
the model that should be returned along with any standard ActionResult. For
example, if your action is supposed to return a User model or a NotFound
result, you can specify this as ActionResult<User>. This helps with compile-
time checks and makes the API more descriptive and self-documenting.
• This is useful in API development, where you might want to return a specific
data type (like a DTO) in case of success or different action results (like 404
NotFound or 400 BadRequest) in case of errors. It also provides clearer
documentation through Swagger or similar API tools, as the expected response
types are explicitly declared.
When to Use?
• Use IActionResult when you need the flexibility to return different types of
action results from your controller methods.
• Use ActionResult<T> when you want to return a specific type but also
maintain the ability to return different HTTP responses.
View Result in ASP.NET Core MVC
In this article, I will discuss the View Result in the ASP.NET Core MVC Applications with
Examples. Please read our previous article, where we discussed the basic concepts
of Action Results in ASP.NET Core MVC Application.
ViewResult in ASP.NET Core MVC
In ASP.NET Core MVC, View Result refers to one of the possible types of action results
returned by the controller action methods. In the controller action method, the return type
indicates what should be rendered or returned to the client (typically a web browser).
A View Result specifically instructs ASP.NET Core MVC to render a view template as the
response to the client’s request. A view is a file with a .cshtml extension that contains the
HTML markup with C# code using Razor syntax. This allows for dynamic HTML generation
based on the data passed from the controller.
The ViewResult class derives from the ActionResult base class. If you go to the definition of
ViewResult class, then you will see the following signature. As you can see, it is a concrete
class with a few properties, overriding the ExecuteResultAsync method, which is used to
generate the dynamic HTML response.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:13 / 03:1110 Sec
244
Creating Model:
Next, create a model class to hold the product data. So, create a class file
named Products.cs within the Models folder and copy and paste the following code into it.
namespace ActionResultInASPNETCoreMVC.Models
{
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Modify the Home Controller:
Next, modify the Home Controller as follows. In the code below, the return type of the Index
action method is ViewResult. The ViewResult returned by the View() method will render
the Index.cshtml Razor view, and we pass the product model object to
the Index.cshtml view to populate dynamic content within the view.
using ActionResultInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
Product product = new Product()
{
Id = 1,
Name = "Test",
};
return View(product);
}
}
}
Modifying the Index View:
Next, modify the Index.cshtml file as follows:
246
@model Product
@{
ViewData["Title"] = "Home Page";
Layout = null;
}
<div class="text-left">
<p>Product ID: @Model.Id</p>
<p>Product Name: @Model.Name</p>
</div>
Now, run the application, and you should get the expected output, as shown in the image
below.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
ExecuteResultAsync Method of PartialViewResult Class:
In ASP.NET Core MVC, the ExecuteResultAsync method of the PartialViewResult class is
used to render a partial view that is returned to the client as part of an HTTP response. The
following are the things to happen when you return a PartialViewResult from an action
method:
• When the MVC framework executes an action that returns a
PartialViewResult, it eventually calls the ExecuteResultAsync method of the
PartialViewResult class.
• Inside the ExecuteResultAsync method, the MVC framework prepares the
data and context required for rendering the partial view.
• It then finds and renders the partial view, which typically includes executing
any Razor code and rendering HTML content.
• After rendering the partial view, the generated HTML content is written to the
response stream and sent back to the client as part of the HTTP response.
How to Use PartialViewResult in ASP.NET Core MVC?
Here’s how you can use PartialViewResult in ASP.NET Core MVC:
1. Create a Partial View: Create a Razor partial view (with the .cshtml
extension) in your project’s appropriate “Views” folder. Partial views typically
contain a portion of HTML markup and any embedded Razor code needed to
generate dynamic content.
2. Create an Action Method: Within your controller, create an action method
that will return a PartialViewResult. This method will process data and pass it
to the partial view.
3. Return a Partial View: In the action method, return a PartialViewResult by
calling the PartialView() method. You can pass a model object to the
PartialView() method if you need to supply dynamic data to the partial view.
Example to Understand PartialViewResult in ASP.NET Core MVC:
248
Let us understand how to use PartialViewResult in ASP.NET Core MVC Application with one
example. First, create a new ASP.NET Core MVC Project using the Model View Controller
template and name the project ActionResultInASPNETCoreMVC.
Creating Model:
Next, create a model class to hold the product data. So, create a class file
named Products.cs within the Models folder and copy and paste the following code into it.
namespace ActionResultInASPNETCoreMVC.Models
{
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Creating a Partial View:
First, create a partial view. Go to the Views=>Shared folder, add a partial view with the
name _ProductDetailsPartialView.cshtml, and copy and paste the following code into it.
@model Product
<div class="text-left">
<p>Product ID: @Model.Id</p>
<p>Product Name: @Model.Name</p>
</div>
Modify the Home Controller:
Next, modify the Home Controller as follows. In the below example, the return type of the
Index action method is PartialViewResult, and internally, the PartialView extension method
returns an instance of PartialViewResult. This PartialView method will render the
“ProductDetailsPartialView.cshtml” partial view, and the product model will populate
dynamic content within the partial view.
using ActionResultInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public PartialViewResult Index()
{
Product product = new Product()
249
{
Id = 1,
Name = "Test",
};
return PartialView("_ProductDetailsPartialView", product);
}
}
}
Now, run the application, and you should see the following output.
Now, it displays the content of that partial view without the layout page. This isn’t very useful
by itself, so a more useful application might be to call this action in an AJAX scenario and
display the returned view.
How to Call Action Method using jQuery AJAX in ASP.NET MVC?
Let us proceed and understand how to call the Action Method, which returns a Partial View
from a regular View using the jQuery AJAX Method.
Modifying Home Controller
First, modify the Home Controller as follows. Here, we have two action methods. The Index
action method returns the View Result, whereas the Details action method returns the Partial
View Result.
using ActionResultInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
250
return View();
}
public PartialViewResult Details(int ProductId)
{
Product product = new Product()
{
Id = ProductId,
Name = "Test Product",
};
return PartialView("_ProductDetailsPartialView", product);
}
}
}
Modify the Index.cshtml View
Next, modify the Index.cshtml view as follows. Here, you can see we are using jQuery AJAX
to call the Details Action Method of the Home Controller, which returns a Partial View. In order
to use jQuery AJAX, we first need to provide the path of the jQuery file, and here we are using
jQuery CDN.
@model Product
@{
ViewData["Title"] = "Home Page";
Layout = null;
}
<div id="someDiv" class="text-left">
</div>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
var rawdata = {'ProductId': '10'};
$.ajax({
type: "GET",
url: "/Home/Details/",
data: rawdata,
251
if (requestedWithHeader.Contains("XMLHttpRequest"))
{
return true;
}
}
return false;
}
}
}
Method Parameter Explanation:
• RouteContext (RouteContext routeContext): Provides context information
about the current route, including the HttpContext for the request. This allows
you to access request data such as headers, query string parameters, route
data, and more, which can be used to make decisions about the validity of the
request for the specific action.
• ActionDescriptor (ActionDescriptor actionDescriptor): This contains
detailed information about the action method being considered for execution.
This includes the controller name, action name, attributes applied to the action,
parameters, and other metadata. This information can be used to identify the
action method and make decisions based on its attributes or other
characteristics.
Then decorate the AjaxOnlyAttribute with the Details action method as shown below.
using ActionResultInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
[AjaxOnly]
public PartialViewResult Details(int ProductId)
{
Product product = new Product()
{
253
Id = ProductId,
Name = "Test Product",
};
return PartialView("_ProductDetailsPartialView", product);
}
}
}
With the above changes in place, the Details action method can only be invoked via AJAX
Request. Now, if you try to access the Details action method using Normal GET or POST
request, you will get a 404 Error.
Checking the Request Path in the Code:
Now, you can also check whether the request is coming via AJAX directly within the action
method. For a better understanding, please modify the Home Controller as follows. If the
request is GET or POST, if it is coming as an AJAX request, it will return
the _ProductDetailsPartialView partial view to the client, and if it is not an AJAX request, it
will return the _InvalidRequestPartialView Partial view to the client.
using ActionResultInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
public PartialViewResult Details(int ProductId)
{
string method = HttpContext.Request.Method;
string requestedWith =
HttpContext.Request.Headers["X-Requested-With"];
if (method == "POST" || method == "GET")
{
if (requestedWith == "XMLHttpRequest")
{
Product product = new Product()
254
{
Id = ProductId,
Name = "Test Product",
};
return PartialView("_ProductDetailsPartialView", product);
}
}
//Create a Partial View to return Invalid Request
return PartialView("_InvalidRequestPartialView");
}
}
}
Creating _InvalidRequestPartialView:
Next, create a Partial View named _InvalidRequestPartialView within
the Views/Shared folder and copy and paste the following code.
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">Invalid Request!</h4>
<p>Sorry, the request you submitted is invalid. Please check your input and try
again.</p>
<!-- Optionally, you can include additional details about the invalid request -->
</div>
With the above changes in place, run the application, and it should work as expected. If you
access the Details action method, it will return the response. But if you access the Details
action method via a normal GET request, you will get the following error message:
255
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
public ActionResult Details(string Category)
{
//Converting Key Name to Pascal case, by default it is Camel Case
var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = null;
try
{
//Based on the Category Fetch the Data from the database
//Here, we have hard coded the data
List<Product> products = new List<Product>
{
new Product{ Id = 1001, Name = "Laptop", Description = "Dell Laptop" },
new Product{ Id = 1002, Name = "Desktop", Description = "HP Desktop" },
new Product{ Id = 1003, Name = "Mobile", Description = "Apple IPhone" }
};
//Please uncomment the following two lines if you want see what happend when
exception occurred
//int a = 10, b = 0;
//int c = a / b;
return Json(products, options);
}
catch(Exception ex)
{
return new JsonResult(new { Message = ex.Message, StackTrace = ex.StackTrace,
ExceptionType = "Internal Server Error" }, options)
{
261
data: rawdata,
dataType: 'json',
success: function (data) {
var items = '';
$.each(data, function (i, item) {
var rows = "<tr>"
+ "<td class='prtoducttd'>" + item.Id + "</td>"
+ "<td class='prtoducttd'>" + item.Name + "</td>"
+ "<td class='prtoducttd'>" + item.Description + "</td>"
+ "</tr>";
$('#tblProducts tbody').append(rows);
});
},
error: function (errorData) {
//respone will be returned here
alert(errorData);
var ErrorResponse = jQuery.parseJSON(errorData.responseText);
alert("Message: " + ErrorResponse.Message);
alert("StackTrace: " + ErrorResponse.StackTrace);
alert("ExceptionType: " + ErrorResponse.ExceptionType);
}
});
});
</script>
Now, run the application, and you should get the expected output, as shown in the image
below.
263
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:07 / 03:1110 Sec
How Does the ExecuteResultAsync Method of ContentResult class Work
in ASP.NET Core MVC?
The ExecuteResultAsync method in the ContentResult class is responsible for executing the
result of an action method that returns custom content. Here is how the ExecuteResultAsync
method works within the ContentResult class:
• Setting Content and Encoding: Before ExecuteResultAsync is called, the
content and, optionally, the content type and encoding of the response are
typically set within the Content property of the ContentResult object.
• Execution: When the action method returns a ContentResult object, the
ASP.NET Core MVC framework calls the ExecuteResultAsync method of that
ContentResult object.
• Output: Within the ExecuteResultAsync method, the content set in the
Content property is written to the response body, along with any configured
content type and encoding.
What are MIME Types?
In ASP.NET Core MVC, MIME types (Multipurpose Internet Mail Extensions) indicate the type
of content the server serves. They are essential for correctly interpreting and displaying
content in web browsers.
MIME types enable browsers to recognize the file type of a file sent via HTTP by the
webserver. As a result, the browser can choose a suitable displaying method. Common MIME
types are, for example, text/html for HTML files or image/jpeg for JPEG files.
How Do We Use ContentResult in ASP.NET Core MVC?
In ASP.NET Core MVC, you can use the ContentResult class to return raw content, such as
text, HTML, XML, or JSON, directly to the client without involving view rendering. Start by
creating a controller action that will return the raw content. For example, let’s say you want to
return a simple plain text message. When returning Plain text, specify the MIME type
as “text/plain,” as shown in the example below.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
265
{
public class HomeController : Controller
{
public ContentResult Index()
{
string htmlContent = "<html><body><h1>Hello, Welcome to Dot Net
Tutorials</h1></body></html>";
return Content(htmlContent, "text/html");
}
}
}
Returning XML:
When returning XML data, specify the MIME type as “application/xml” as shown in the
example below.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ContentResult Index()
{
string xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data><item>Hello
Dot Net Tutorials</item></data>";
return Content(xmlContent, "application/xml");
}
}
}
Returning JSON:
When returning JSON data, specify the MIME type as “application/json” as shown in the
example below.
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace ActionResultInASPNETCoreMVC.Controllers
{
267
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:09 / 03:1110 Sec
• Creating a FileResult Object: To return a file from a controller action, you
create a FileResult object.
• Setting File Information: Before returning the FileResult from the action
method, we need to set properties such as the file content, content type, and
file download name.
• Execution: When the action method returns a FileResult object, the
ASP.NET Core MVC framework handles it by calling the ExecuteResultAsync
method of the specific FileResult subclass.
• Writing Content to Response: Within the ExecuteResultAsync (Parent
ActionResult class ExecuteResultAsync) method, the file content is written to
the response body along with appropriate HTTP headers such as Content-
Disposition for specifying the filename and Content-Type for specifying the
file’s MIME type.
Understanding Different MIME Types:
When working with File Result, we need to understand the different MIME types that we used
to specify the file type being returned from the action method. The following are the different
MIME types:
Image MIME Types:
• JPEG: image/jpeg
• PNG: image/png
• GIF: image/gif
270
• BMP: image/bmp
• SVG: image/svg+xml
• WebP: image/webp
Common File MIME Types:
• PDF: application/pdf
• Microsoft Word: application/msword
• Microsoft Excel: application/vnd.ms-excel
• Microsoft PowerPoint: application/vnd.ms-powerpoint
• ZIP Archive: application/zip
• JSON: application/json
• XML: application/xml
• Text: text/plain
• HTML: text/html
Audio and Video MIME Types:
• MP3 Audio: audio/mpeg
• WAV Audio: audio/wav
• OGG Audio: audio/ogg
• MP4 Video: video/mp4
• WebM Video: video/webm
• OGG Video: video/ogg
Example to Understand File Result in ASP.NET Core MVC:
Let us understand the FileResult in the ASP.NET Core MVC Application with a few
examples. When returning files or images from your ASP.NET Core MVC controller actions,
setting the appropriate MIME type is important to ensure the browser understands how to
handle the content. For example, you can set the mime type as image/jpeg for JPEG images.
Before proceeding further, let us create a folder named PDFFiles within the wwwroot folder
and then add a PDF file named Sample.pdf to this PDFFiles folder. Your folder structure
should look like the one shown below.
You can also provide additional options when returning files, such as specifying the file
download name, enabling browser caching, and specifying the content disposition. So, please
modify the Home Controller as follows. The Index action method sends a PDF file to the client,
with explicit control over how the file should be presented (either as a download or directly
browsed in the browser). The following code also sets the Content-Disposition header directly
to manage file delivery behaviors. The following code is self-explained, so please go through
the comment lines.
using Microsoft.AspNetCore.Mvc;
using System.Net.Mime;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public FileResult Index()
{
//Get the File Path
string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\PDFFiles\\" +
"Sample.pdf";
//Convert to Byte Array
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
//Set Content Disposition
//creates a new instance of ContentDisposition,
//which is used to specify the presentation and filename of the file in the HTTP header
var contentDisposition = new ContentDisposition
{
//Sets the default filename for the file when the user downloads it.
FileName = "MySample.pdf",
//Indicates that the file should not be displayed inline in the browser window.
//Instead, it prompts the user to download the file.
//Setting this to true would display the file directly in the browser, if supported.
Inline = false
};
//Appends the Content-Disposition header to the HTTP response.
//The header's value is generated from the contentDisposition object,
274
//instructing the browser how to handle the received file based on the Inline property
and FileName.
Response.Headers.Append("Content-Disposition", contentDisposition.ToString());
//Return the File
//The File method constructs a FileResult using the byte array (fileBytes) and the MIME
type ("application/pdf").
//This tells the client that the file is a PDF, aiding the browser or client application in
handling the file appropriately.
return File(fileBytes, "application/pdf");
}
}
}
Using Physical Files:
You can also return physical files from the server’s file system. To better understand, please
modify the Home Controller as follows. The Index action method is used to serve a PDF file
directly from the file system to the client using the PhysicalFile method. The following code is
self-explained, so please go through the comment lines.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public FileResult Index()
{
//Get the File Path
string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\PDFFiles\\" +
"Sample.pdf";
//Return the Physical File
//The PhysicalFile method returns the file located at the specified filePath directly to
the client.
//The PhysicalFile method is a convenient way to return files without loading them into
memory:
//filePath: The path to the file that is to be served.
//"application/pdf": The MIME type of the file.
275
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
If you go to the definition of RedirectResult, you will see that it is a class with 3 constructors,
a few properties, and one overriding method, as shown in the image below.
namespace ActionResultInASPNETCoreMVC.Controllers
}
Using RedirectResult Helper Method:
Alternatively, you can use the Redirect helper method provided by the Controller class to
create a RedirectResult. This method simplifies the creation of redirect results.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
return Redirect("https://dotnettutorials.net");
}
Note: Don’t use the other overloaded constructor versions, or you will make your redirection
permanent.
RedirectToRouteResult in ASP.NET Core MVC
In ASP.NET Core MVC, RedirectToRouteResult is an action result that redirects the client to
a specified route. It allows you to redirect the user to a different action within the same
controller or to an action in a different controller. Routes in ASP.NET Core MVC define how
URLs are mapped to controller actions. By using RedirectToRouteResult, you can take
278
advantage of these route definitions to dynamically redirect users based on the route
configuration.
How Does ExecuteResultAsync Method of RedirectToRouteResult class
Works in ASP.NET Core MVC?
The ExecuteResultAsync method in the RedirectToRouteResult class is responsible for
executing the result of an action method that returns a redirect to a route result. Here is how
the ExecuteResultAsync method works within the RedirectToRouteResult class:
• Setting Route Values: Before returning the RedirectToRouteResult from the
action method, we need to set the RouteValues property to specify the route to
which the client should be redirected. The route values typically include the
controller, action, and any additional parameters required by the route.
• Execution: When the action method returns a RedirectToRouteResult object,
the ASP.NET Core MVC framework handles it by calling the
ExecuteResultAsync method of that RedirectToRouteResult object.
• Redirecting: Within the ExecuteResultAsync method, the ASP.NET Core
MVC framework generates an HTTP redirect response (status code 302) with
the URL constructed based on the specified route values. This instructs the
client’s browser to navigate to the specified route.
Example to Understand RedirectToRouteResult in ASP.NET Core MVC
Let us understand RedirectToRouteResult with some examples. First, we need to create
a Route with the name AboutRoute within our Program.cs class file, which should execute
the About Action method of the Home Controller. So, modify the Home Controller as follows.
Here, you can see first, we have registered the AboutRoute and then the default Route.
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Mvc;
using System;
namespace ActionResultInASPNETCoreMVC
builder.Services.AddControllersWithViews();
279
if (!app.Environment.IsDevelopment())
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "AboutRoute",
pattern: "about",
);
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
280
}
Modifying the Home Controller:
Next, modify the Home Controller as follows. Here, you can see within the Index action
method, we redirect to the AboutRoute using the RedirectToRoute method.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
// You need to specify the Route Name, not the Route Pattern
return RedirectToRoute("AboutRoute");
}
Remember that RedirectToRouteResult allows you to define more complex redirection
scenarios involving different controllers, actions, and route values. It is useful when
281
abstracting the route logic from the specific controller and action names. In the below
example, we are directing the user to the AboutRoute Route with some data.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
// You need to specify the Route Name, not the Route Pattern
}
The RedirectToRouteResult is also used whenever we need to move from one action method
to another within the same or different controller in an ASP.NET Core MVC Application. For
example, in the below code, we redirect to the Home Controller’s About action method from
the Home Controller’s Index action method.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
282
// You need to specify the Route Name, not the Route Pattern
}
Note: Specifying the controller’s name is optional if you redirect to an action method within
the same controller, but navigating to a different controller is mandatory.
RedirectToActionResult in ASP.NET Core MVC
In ASP.NET Core MVC, RedirectToActionResult is an action result that redirects the client to
another action within the same controller or a different controller. It allows you to redirect
users to a different action based on the action name and controller name. Specifying the
controller’s name is optional if you redirect to an action method within the same controller,
but navigating to a different controller is mandatory.
How Does the ExecuteResultAsync Method of RedirectToActionResult
class Work in ASP.NET Core MVC?
The ExecuteResultAsync method in the RedirectToActionResult class is responsible for
executing the result of an action method that returns a redirect to an action result. Here is
how the ExecuteResultAsync method works within the RedirectToActionResult class:
• Setting Action and Controller Names: Before returning the
RedirectToActionResult from the action method, we need to set the
283
namespace ActionResultInASPNETCoreMVC.Controllers
// return RedirectToAction("AboutUs");
}
284
}
In the above example, when the Index action is invoked, it performs some logic (which you
can replace with your logic). Then, it uses RedirectToAction to redirect the user to the
AboutUs action method within the same controller. You can also use additional overloads of
RedirectToAction to provide route values and query parameters:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
return $"Hello and Welcome to Dot Net Tutorials, Id{id}, Name:{name} ";
}
Differences Between RedirectResult, RedirectToRoute Result, and
RedirectToActionResult in ASP.NET Core MVC
285
• 3XX: Redirection Response (Example. 301, 302, 304, etc.). Whenever you
get 3XX as the response code, it means it is re-directional, i.e., some re-
directional is happening on the server. Status codes in the 3xx range indicate
that the client needs further action to complete the request. These codes are
used when a resource has been moved or is temporarily unavailable, and the
client needs to take additional steps to access the resource.
• 4XX: Client Error Response (Example: 400, 401, 404, 405,
etc.). Whenever you get 4XX as the response code, it means there is some
problem with your request. Status codes in the 4xx range indicate that the
client’s request was unsuccessful due to an error on the client’s request. These
codes are often associated with issues such as invalid requests, unauthorized
access, or missing resources.
• 5XX: Server Error Response (Example: 500, 502, 503, 504,
etc.). Whenever you get 5XX as the response code, it means there is some
problem in the server. Status codes in the 5xx range indicate that the server
encountered an error while processing the client’s request. These codes are
typically associated with issues on the server side, indicating that the requested
action could not be completed due to server-related problems.
Status Results in ASP.NET Core MVC
Status Results in ASP.NET Core MVC are action results that allow you to return HTTP status
codes along with optional content. Several types of Status Results are available in ASP.NET
Core MVC. They are as follows:
Ad
1/2
00:23
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People Know
• StatusCodeResult: This represents a response with a specific HTTP status
code and no additional content.
• NotFoundResult: This represents a response with the HTTP status code
404 (Not Found).
• BadRequestResult: Represents a response with the HTTP status code 400
(Bad Request).
• OkResult: Represents a response with the HTTP status code 200 (OK).
• UnauthorizedResult: Represents an HTTP 401 (Unauthorized) response.
Status Results indicate success, failure, or various error conditions to the client. Using Status
Results, you can ensure that the client understands the result of their request based on the
provided HTTP status code.
StatusCodeResult in ASP.NET Core MVC:
In ASP.NET Core MVC, the class StatusCodeResult returns an HTTP status code without
any additional content or response body. But, using the StatusCode helper method, we can
return optional content. It’s typically used when you explicitly want to indicate a specific HTTP
status code for a response. Let’s modify the Home Controller as follows to understand this
concept in ASP.NET Core MVC.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
287
Now, if you inspect the request, you will see the server returns a 404 status code, as shown
in the image below.
288
If you visit Home/CustomStatusCodeExample, you will get the 403 response we set in the
action method.
Now, if you inspect the request using the browser developer tool, you will see the server is
returning the 403 status code, as shown in the image below.
289
If you want to return a message along with the HTTP Status Code, you need to use the other
overloaded version, which takes the object value as a parameter. In this case, we must use
the IActionResult and ActionResult as the action method’s return type. For a better
understanding, please modify the Home Controller class as follows:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ActionResult NotFoundExample()
{
// Return a 404 Not Found response
return StatusCode(404, new { message = "Resource Not Found" });
}
public IActionResult CustomStatusCodeExample()
{
// Return a custom status code
return StatusCode(403, "Resource Not Found");
}
}
}
The StatusCodeResult class is indeed used in ASP.NET Core MVC to create and return the
desired HTTP status code as a response from the controller action.
HttpUnauthorizedResult in ASP.NET Core MVC
In ASP.NET Core MVC, the UnauthorizedResult class returns an HTTP 401 (Unauthorized)
response. This is often used when a user is not authenticated and lacks the credentials to
access a particular resource or perform an action. Returning an UnauthorizedResult is the
same as returning StatusCodeResult with HTTP Status Code Unauthorized, i.e., 401; it’s
more readable.
In the example below, the UnauthorizedExample action returns a 401 (Unauthorized)
response using the UnauthorizedResult class. The shorthand method Unauthorized() can
also be used to achieve the same result.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
291
This is useful when you want to indicate to the client that the request was not authorized due
to a lack of proper authentication or authorization credentials.
NotFoundResult in ASP.NET Core MVC
In ASP.NET Core MVC, the NotFoundResult class returns an HTTP 404 (Not Found)
response. This is often used when a requested resource is unavailable on the server.
For a better understanding, please modify the Home Controller class as follows. In the
example below, the NotFoundExample action method returns a 404 (Not Found) response
using the NotFoundResult class. The shorthand method NotFound() can also be used to
achieve the same result.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public NotFoundResult NotFoundExample()
{
// Return a 404 Not Found response
return new NotFoundResult();
// Or use the shorthand:
293
// return NotFound();
}
}
}
Now, if you want to return some message along with the 404 Status Code, you need to use
the other overloaded version of the helper method, which takes the object value as a
parameter. For a better understanding, please modify the Home Controller class as follows:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public ActionResult NotFoundExample()
{
// Return a 404 Not Found response
//return new NotFoundResult("Resource Not Found");
// Or use the shorthand:
return NotFound("Resource Not Found");
}
}
}
This is useful when you want to indicate to the client that the requested resource does not
exist on the server.
OkResult in ASP.NET Core MVC:
In ASP.NET Core MVC, the OkResult class returns an HTTP 200 (OK) response. This is
often used when the server successfully handles a requested resource. Along with OKResult,
you can also use the Ok method, which is also used to return an HTTP 200 (OK) response,
indicating that the request was successful.
For a better understanding, please modify the Home Controller class as follows. In the
example below, the OkExample action method returns a 200 (OK) response using the
OKResult class. The shorthand method OK() can also be used to achieve the same result.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
294
In ASP.NET Core MVC, the ObjectResult is an action result that returns an arbitrary object to
the client. Unlike other result types such as JsonResult, ContentResult, or FileResult, which
have predefined formats, the ObjectResult allows you to return any object from a controller
action, and ASP.NET Core MVC will serialize it to the appropriate format based on the
request’s Accept header and the available formatters configured in the application. This
means that you can return various types of content, such as JSON, XML, or even custom
formats, depending on the client’s preferences and the configuration of your application.
The ObjectResult class derives from the ActionResult base class and implements the
IStatusCodeActionResult interface. If you go to the definition of ViewResult class, then you
will see the following signature. As you can see, it is a concrete class with a few properties
and methods, and it overrides the ExecuteResultAsync method.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
How Does the ExecuteResultAsync Method of ObjectResult class Work in
ASP.NET Core MVC?
The ExecuteResultAsync method in the ObjectResult class is responsible for executing the
result of an action method that returns an object result. Here is how the ExecuteResultAsync
method works within the ObjectResult class:
• Setting Response Data: Before returning the ObjectResult from the action
method, we need to set the Value property to specify the object that will be
serialized and sent as the HTTP response body. We can also optionally set
other properties such as StatusCode, SerializerSettings, etc.
• Execution: When the action method returns an ObjectResult object, the
ASP.NET Core MVC framework handles it by calling the ExecuteResultAsync
method of that ObjectResult object.
• Serialization and Writing to Response: Within the ExecuteResultAsync
method, the ASP.NET Core MVC framework serializes the Value object into
the appropriate format (JSON, XML, etc.) based on the content negotiation
296
process and writes it to the response body along with the specified status code
and content type.
Example to Understand Object Result in ASP.NET Core MVC:
Let us understand ObjectResult in ASP.NET Core MVC with a few examples. First, modify
the Home Controller as follows. Here, you can see that while creating the ObjectResult
instance, we pass the person object to the constrictor. By default, ASP.NET Core will serialize
the person object to JSON because JSON serialization is the most common use case.
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult GetPerson()
{
var person = new { FirstName = "Pranaya", LastName = "Rout", Age = 35 };
// Return an ObjectResult with JSON serialization
return new ObjectResult(person);
// Or use the shorthand:
// return Ok(person);
}
}
}
Setting ObjectResult Properties:
We can also set the status code, content type, and other properties of the response using the
properties of the ObjectResult class. For a better understanding, please modify the Home
Controller as follows. Here, while creating the ObjectResult instance, we are setting the
Status Code to 200 and ContentTypes to “application/json.”
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult GetPerson()
{
var person = new { FirstName = "Pranaya", LastName = "Rout", Age = 35 };
var result = new ObjectResult(person)
297
{
StatusCode = 200, // HTTP status code
ContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection
{
"application/json" // Content type(s)
}
};
return result;
}
}
}
In most cases, if you’re returning data in JSON format, using the ObjectResult is not strictly
necessary, as the Ok method, which returns a 200 (OK) response, can be used as shorthand:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult GetPerson()
{
var person = new { FirstName = "Pranaya", LastName = "Rout", Age = 35 };
// Return a 200 OK response with JSON serialization
return Ok(person);
}
}
}
This approach is cleaner and commonly used for returning data in JSON format for APIs and
similar scenarios.
Differences Between ObjectResult and OKResult in ASP.NET Core MVC:
In ASP.NET Core MVC, both ObjectResult and OkResult are used to return HTTP responses,
but they are used in different scenarios and offer different levels of customization. Let’s
understand the differences between these two result types:
ObjectResult
• It is used to return an HTTP response containing an arbitrary object that will
be serialized and returned as the response body. It’s commonly used to return
data in various formats, such as JSON, XML, or other custom content types.
298
• This can be used to return any status code, not just 200 OK. You can set
different status codes based on your application’s requirements.
If you need to return different status codes or provide custom content types, or if you are
building more complex APIs, then you need to use ObjectResult as shown in the below
example:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult GetPerson()
{
var person = new { FirstName = "Pranaya", LastName = "Rout", Age = 30 };
var result = new ObjectResult(person)
{
StatusCode = 201, // Created status code
ContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection
{
"application/json", // JSON content type
"application/xml" // XML content type
}
};
return result;
}
}
}
OKResult
• It is specifically used to return a standard HTTP 200 (OK) response.
• It always returns a 200 OK status code suitable for explicitly indicating success.
• This does not allow you to provide content to be serialized directly. It’s a
simple way to indicate success without including a response body.
In most cases, if you are returning data in JSON format and you want to indicate a successful
response, you can use OK, as shown in the code below:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
299
specified by the client. If the server can’t fulfill any of the client’s preferred
formats, it will typically respond in its default format.
• Formatters: In ASP.NET Core, output formatters handle the actual
transformation of data into the desired format.
• Returning Results: In your controller actions, you can use methods like Ok(),
ObjectResult(), etc., and the content negotiation process will automatically
ensure that the returned data is in the format preferred by the client. If you want
to bypass content negotiation for a particular action and always return data in
a specific format, you can use methods like Json() to return JSON data.
• Input Formatters: While output formatters deal with responses, input
formatters handle incoming request data. This allows the client to send data in
various formats (e.g., JSON, XML), and the input formatter will try to deserialize
it into the appropriate object type for use within the application.
How Do We Return XML Response in ASP.NET Core?
By default, ASP.NET Core returns the data in JSON format. If you want to return XML data,
then you need to configure XML Formatter as follows:
builder.Services.AddControllers().AddXmlSerializerFormatters();
Note: We must create an ASP.NET Core Web API Project to test this. We will discuss this in
detail in our ASP.NET Web API section.
When Should We Use Object Result in ASP.NET Core MVC?
The following are some of the scenarios when you might consider using ObjectResult:
• Custom Status Codes: You need to return a specific HTTP status code
other than the standard ones (e.g., 201 Created, 404 Not Found, etc.).
• Custom Content Types: You want to specify a non-standard content type for
the response, like XML, plain text, or a custom media type.
• API Responses: When building APIs, you might want to return responses
with a consistent structure, including status codes, data, and possibly
additional metadata.
• Multiple Formats: You want to provide different response formats (e.g.,
JSON, XML) based on the client’s content negotiation.
EmptyResult in ASP.NET Core MVC
In this article, I am going to discuss the EmptyResult in ASP.NET Core MVC Web
Application with Examples. Please read our previous article, where we discussed the Object
Result in ASP in ASP.NET Core MVC Application.
EmptyResult in ASP.NET Core MVC
In ASP.NET Core MVC, the EmptyResult class is used to return an empty HTTP response
with no content. This is commonly used when you want to indicate that a request has been
successfully processed, but there is no specific content to return in the response body. Here’s
how you can use EmptyResult in an ASP.NET Core MVC controller action:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult ProcessRequest()
301
{
// Perform some processing
// Return an empty HTTP response
return new EmptyResult();
}
}
}
In the example above, the ProcessRequest action performs some processing and then
returns an EmptyResult to indicate the successful processing of the request. This can be
useful when you don’t need to send any data in the response body but still want to signal that
the request was handled successfully.
The EmptyResult is also often used in conjunction with other HTTP status codes to provide
meaningful responses. For example, you might return an EmptyResult with a 204 No Content
status code to indicate that the request was successful, but there’s no additional content to
send:
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:03 / 03:1110 Sec
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult DeleteResource()
{
// Delete the resource
// Return a 204 No Content response with an EmptyResult
return NoContent();
}
}
}
In this example, the NoContent method returns a 204 No Content response, which is
appropriate when you want to signal that the resource has been successfully deleted. Still,
there’s no content to include in the response body.
When to Use EmptyResult in ASP.NET Core MVC?
The EmptyResult class in ASP.NET Core MVC is used when you want to return an empty
HTTP response with no content in the response body. It’s typically used to indicate the
302
successful handling of a request where there’s no specific data to return. Here are some
scenarios where you might consider using EmptyResult:
• Deletion Operations: After successfully deleting a resource, you might want
to return an empty response to indicate that the deletion was successful. This
is often accompanied by an appropriate status code, such as 204 No Content.
• Confirmation Responses: In cases where a request’s primary purpose is to
confirm or acknowledge an action, you can use EmptyResult to signal that the
confirmation has been processed.
• Webhooks: When receiving webhook notifications, you might perform certain
actions without needing to return any content. In such cases, an EmptyResult
can indicate that the webhook notification was successfully processed.
• Status or Heartbeat Endpoints: For endpoints that are used for checking
the status of a service or to ensure that the service is up and running, you might
return an empty response as a simple confirmation.
• Response Codes without Data: When you need to return specific HTTP
status codes (like 204 No Content) to indicate a certain outcome without any
additional response body.
Ultimately, using EmptyResult is a way to communicate that a request was successfully
processed without the need for returning any specific content in the response body.