Introduction To ASP Full Book
Introduction To ASP Full Book
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
7
2. Tag Helpers
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.
jQuery AJAX. In simple words, we can say that it is a mechanism to bypass the Same-
Origin Policy of a Web browser.
Validation: All four methods support the validation feature, which is used to validate the
HTTP Request Data. We can implement validation using DataAnnotations attributes and
Fluent API. DataAnnotations includes built-in validation attributes for different validation
rules, which can be applied to the properties of the model class. Simultaneously, we need to
use Fluent AP for condition-based validation.
Formatter Mapping: Except for the AddRazorPages method, all other methods support the
Formatter Mapping feature. This feature is used to format the output of your action method,
such as JSON or XML.
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.
10
Conquering the clouds on a journey to Ta Xua with the team - Road Trip Vietnam Team
- Nếm TV00:19 / 02:5410 Sec
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.
12
Once you click on the Next button, it will open the Configure Your New Project window.
Here, you must provide the necessary information to create a new project. First, give an
appropriate name for your project (FirstCoreMVCWebApplication), set the location where
you want to create this project, and the solution name for the ASP.NET Core Web
application. And finally, click on the Create button, as shown in the image below.
Once you click on the Next button, 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.
13
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.
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.
15
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.
16
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
17
});
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.
21
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
23
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:
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:
24
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
{
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" },
25
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();
}
}
}
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
{
26
A view in ASP.NET Core MVC Application is responsible for UI, i.e., application data
presentation. That means we display information about the website on the browser using
the views only. A user generally performs all the actions on a view, such as a button click,
form, list, and other UI elements.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People Know
Where are Views Placed in ASP.NET Core MVC Application?
By default, Views are available inside the Views folder at the root. Usually, views are
grouped into folder names with the application controller. Each controller will have its own
folder in which the controller-specific view files will be stored. The controller-specific folders
will be created within the Views folder only.
Let’s say we have an ASP.NET Core MVC application with two controllers, i.e.,
HomeController and StudentController. The HomeController is created with the following
three action methods.
1. AboutUs()
2. ContactUs()
3. Index()
On the other hand, StudentController is created with the following four action methods.
1. Index()
2. Details()
3. Edit()
4. Delete()
Then, the following is the folder and file structure of the Views.
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.
28
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.
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();
}
}
}
29
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.
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.
So, right-click on the Home folder and then select the Add => View option, which will open
the Add View window, as shown in the image below. You need to select the Razor View
and click the Add button, as shown in the image below.
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.
31
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.
32
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.
34
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.
36
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.
37
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
39
you want to create this project, and the solution name for the ASP.NET Core Web
application. And finally, click on the Create button, as shown in the image below.
Once you click on the Next button, 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.
40
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();
}
41
}
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;
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()
{
42
return DataSource();
}
}
}
Program.cs:
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;
43
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
public JsonResult Index()
{
StudentRepository repository = new StudentRepository();
List<Student> allStudentDetails = repository.GetAllStudent();
return Json(allStudentDetails);
}
public JsonResult GetStudentDetails(int Id)
{
StudentRepository repository = new StudentRepository();
Student studentDetails = repository.GetStudentById(Id);
return Json(studentDetails);
}
}
}
With the above changes in place, now run the application and check the above two
methods. it should work as expected, as shown in the image below.
44
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?
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.
45
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;
47
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),
// new StudentRepository())); // by default singleton
//builder.Services.Add(new ServiceDescriptor(typeof(IStudentRepository),
// typeof(StudentRepository), ServiceLifetime.Singleton)); // singleton
//builder.Services.Add(new ServiceDescriptor(typeof(IStudentRepository),
// typeof(StudentRepository), ServiceLifetime.Transient)); // Transient
//builder.Services.Add(new ServiceDescriptor(typeof(IStudentRepository),
// typeof(StudentRepository), ServiceLifetime.Scoped)); // Scoped
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
//Configuring the MVC middleware to the request processing pipeline
endpoints.MapDefaultControllerRoute();
});
app.Run();
48
}
}
}
Constructor Injection in ASP.NET Core MVC Application
Once we register the service, the IoC container automatically performs constructor injection
if a service type is included as a parameter in a constructor. Let us modify the
HomeController, as shown below, to use Constructor Dependency Injection in the ASP.NET
Core MVC Application.
using FirstCoreMVCWebApplication.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace FirstCoreMVCWebApplication.Controllers
{
public class HomeController : Controller
{
//Create a reference variable of IStudentRepository
private readonly IStudentRepository? _repository = null;
//Initialize the variable through constructor
public HomeController(IStudentRepository repository)
{
_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);
}
}
}
49
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.
{
public JsonResult Index([FromServices] IStudentRepository repository)
{
List<Student> allStudentDetails = repository.GetAllStudent();
return Json(allStudentDetails);
}
}
}
Run the application, and you will get the expected output, as shown below.
{
public JsonResult Index()
{
var services = this.HttpContext.RequestServices;
IStudentRepository? _repository =
(IStudentRepository?)services.GetService(typeof(IStudentRepository));
List<Student>? allStudentDetails = _repository?.GetAllStudent();
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.
52
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
53
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.
54
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.
55
development. You can specify different settings for different environments (like
Development, Staging, and Production) in this file.
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
57
builder.Services.AddControllersWithViews();
if (!app.Environment.IsDevelopment())
58
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();
}
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.
59
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.
60
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
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>
63
<body>
<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.
64
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.
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:
66
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;
67
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>
68
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.
69
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
70
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 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()
{
71
//Using ViewBag
ViewBag.Title = "Student Details Page";
//Using ViewData
ViewData["Header"] = "Student Details";
//Creating Student Object to Hold Student data
Student student = new Student()
{
StudentId = 101,
Name = "James",
Branch = "CSE",
Section = "A",
Gender = "Male"
};
//Passing the Model Object as a Parameter to View Extension Method
//It means the View is going to be a Strongly Type View for the Student Model
return View(student);
}
}
}
Changes in Details.cshtml View:
To create a strongly typed view in the ASP.NET Core MVC Application, we need to specify
the model type within the view by using the @model directive. Here, the Student class will
be our model, which we passed from our action method as a parameter to the View
Extension method. So, we need to specify the model for the view, as shown below.
@model FirstCoreMVCApplication.Models.Student
The above statement will tell the view that we will
use FirstCoreMVCApplication.Models.Student as the model for this view. In the directive
(@model), m is in lowercase, and the statement should not be terminated with a
semicolon.
Then, to access the model object properties, you can use @Model. Here, the letter M is
in uppercase. So, in our example, we can access the Student objects properties such as
Name, Gender, Branch, and Section by using @Model.Name, @Model.Gender,
@Model.Branch, and @Model.Section, respectively. So, Modify the Details.cshtml view
file as shown below to make the view a Strongly Typed View.
@{
Layout = null;
}
72
<!DOCTYPE html>
@model FirstCoreMVCWebApplication.Models.Student
<html>
<head>
<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.
73
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
{
75
//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">
78
<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>
79
</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):
82
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()
{
83
return View();
}
}
}
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>
84
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
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.
85
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
86
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";
}
88
<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
90
case, 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();
}
91
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.
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()
{
96
return View();
}
// POST: Process the form
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult SubmitForm(MyModel model)
{
if (ModelState.IsValid)
{
// Process your model here (e.g., save to database)
// Store a message in TempData
TempData["SuccessMessage"] = "Form submitted successfully!";
// Redirect to a GET method
return RedirectToAction(nameof(Success));
}
// If model state is invalid, show the form again
return View("Index", model);
}
// GET: Success page
public IActionResult Success()
{
return View();
}
}
}
Create the Views
You’ll need a view for the form and another for the confirmation.
Index.cshtml (Form View):
Create a view with the name Index.cshtml within the Views/Home folder, and then copy
and paste the following code:
@model FirstCoreMVCWebApplication.Models.MyModel
<form asp-action="SubmitForm" asp-controller="Home" method="Post">
<div asp-validation-summary="ModelOnly"></div>
<div>
97
<label asp-for="Name"></label>
<input asp-for="Name" />
<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:
98
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:
99
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.
100
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.
102
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 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.
103
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.
104
Once you click the Create button, the project will be created using the Model-View-
Controller template with the following folder and file structure.
105
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.
108
/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
109
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.
namespace RoutingInASPDotNetCoreMVC
{
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" }
111
);
//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
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
113
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.
To achieve the above URL Patterns, we need to modify
the MapControllerRoute Middleware Component as follows. As you can see, as part of the
pattern, we specify the id parameter (pattern: “{controller}/{action}/{id}”). Here, the id
parameter is not optional; it is mandatory, and while accessing any action method, it is
mandatory to pass the Id parameter value.
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";
}
}
}
114
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
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.
On the other hand, we need to make the id parameter of the Details action method optional.
It means the Details action method should be invoked using the following two URLs.
https://localhost:44359/Student/Details
https://localhost:44359/Student/Details/10
In order to achieve this, we need to use optional parameters in our convention-based
routing by adding a question mark “?” to the optional route parameter constraint. In our
example, we 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
117
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.
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: "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.
Custom Route Constraints in ASP.NET Core MVC allow us to enforce specific rules on the
routes at the routing level, which can help to ensure that URLs match expected formats,
values, and conditions. These constraints can be used to validate parameters in the URL
before the request even reaches the controller action.
Custom route constraints allow us to implement complex route validation logic (such as
being an integer, having a specific range of values, or matching a regular expression) for
the route parameters that cannot be expressed with standard constraints like int, guid,
minlength, etc.
How do you Create a Custom Route Constraint in ASP.NET Core?
To create a Custom Route Constraint in ASP.NET Core MVC, we must create a class that
implements the IRouteConstraint interface. This interface has a single method
called Match, and we need to implement this Match method to define our custom constraint
logic. This method contains the logic to check whether a particular URL parameter meets a
specific requirement and returns a boolean indicating whether the constraint is met. If you
go to the definition of the IRouteConstraint interface, you will see the following.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:08 / 03:1110 Sec
});
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",
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();
123
}
public string Details(string id)
{
return $"Details({id}) Action Method of StudentController";
}
}
}
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:
125
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
{
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>()
{
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
public List<Student> GetAllStudents()
{
return students;
}
//This method is going to return a student based on the student id
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 return the courses of a student based on the student id
public List<string> GetStudentCourses(int studentID)
{
//Real-Time you will get the courses from database, here we have hardcoded the data
126
// 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}/{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;
128
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>()
{
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)
129
{
//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" };
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()
130
{
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 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;
131
}
}
}
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 the output as expected.
https://localhost:44359/Home/Details/10
Attribute Routing with Optional Parameters in ASP.NET Core MVC
Application:
We can also make the Route Parameter optional in Attribute Routing. You can define a
Route Parameter as optional by adding a question mark (?) to the route parameter. You
can also specify the default value by using the parameter = value.
In our example, the Details(int id) action method of the HomeController is currently
executed only if we pass the id parameter value. If we do not pass the id parameter value,
we will get a 404 error. For example, if we navigate to the following URL, we will get a 404
error.
https://localhost:44359/Home/Details
Let us modify the Route attribute of the Details action method as shown below to make the
route parameter id optional by adding “?” at the end, i.e. [Route(“Home/Details/{id?}”)].
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;
132
}
}
}
Now run the application and navigate to the following URL. You will see the output as
expected instead of a 404 error.
https://localhost:44359/Home/Details
We can also make the parameter optional by specifying a default value. For a better
understanding, please modify the Home Controller class as follows. Within the Route
Attribute of Details action method, we have specified the default value for the id parameter
as 10.
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=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;
133
namespace RoutingInASPDotNetCoreMVC.Controllers
{
public class HomeController : Controller
{
[Route("")]
[Route("MyHome")]
[Route("MyHome/Index")]
public string StartPage()
{
return "StartPage() Action Method of HomeController";
}
}
}
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";
134
}
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.
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()
{
135
[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";
}
}
}
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;
139
}
[HttpGet("~/About")]
public string About(int id)
{
return "About() Action Method of HomeController";
}
}
}
What is the Difference Between [Route] and [HttpGet], [HttpPost], etc.,
Attributes?
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
140
[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.
141
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
[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
//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("/")]
}
143
}
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.
Attribute Routing vs Conventional Routing in
ASP.NET Core
In this article, I will discuss Attribute Routing vs Conventional Routing in ASP.NET
Core MVC Applications with Examples. Please read our previous article
discussing ASP.NET Core Attribute Routing using Tokens with Examples.
Attribute Routing vs Conventional Routing in ASP.NET Core
In ASP.NET Core, Routing determines how an HTTP request matches a controller action.
There are two primary approaches to routing in ASP.NET Core: Attribute Routing and
Conventional Routing. Each approach has its unique characteristics, advantages, and use
cases.
Conventional Routing in ASP.NET Core
Conventional routing uses a predefined pattern to map requests to controller actions. It
involves defining routes in the Program.cs file. This approach relies on a predefined pattern
to match the URL paths to the corresponding controller actions. It typically specifies
placeholders for the controller name, action name, and optional parameters. This approach
is useful for applications with a clear and consistent URL structure across the entire
application.
Characteristics of Conventional Routing:
Routes are defined globally in a centralized location, typically in the
Program.cs file.
It implicitly uses route templates associated with controllers and actions
through naming conventions.
Parameters can be specified within the route templates to capture values
from the URL.
Advantages of Conventional Routing:
Simplifies route management by centralizing route definitions, making it
easier to understand and manage the application’s URL structure.
Ideal for large applications with a hierarchical URL structure that follows a
consistent pattern.
Disadvantages of Conventional Routing:
144
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.
145
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:33 / 03:1110 Sec
146
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.
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.
147
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.
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
As you can see in the above layout file, it contains the standard HTML, head, title, and body
elements. As the above elements are present in the layout file, you don’t have to repeat
them in each and every view of your application that uses the above Layout file.
The View or Page-Specific title is retrieved by using the @ViewBag.Title expression. For
example, when the “index.cshtml” view is rendered using this layout view, then
the index.cshtml view will set the Title property on the ViewBag. This is then retrieved by
the Layout view using the expression @ViewBag.Title and set as the value for the <title>
tag.
The @RenderBody() method specifies the location where the View or Page-Specific
content will be injected. For example, if the “index.cshtml” view is rendered using this layout
view, then the index.cshtml view content will be injected at the @RenderBody() location.
Now, let us modify the _Layout.cshtml page again, as shown below, to include the header,
footer, left navigation menus, and main content area section.
<!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>
149
</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
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");
150
// 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.
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCApplication.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
public ViewResult Details()
{
return View();
}
}
}
151
Next, navigate to the Home/Details URL, which should display the page below.
152
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.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:18 / 03:1110 Sec
153
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.
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.
154
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>
</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.
155
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.
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>
156
</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>
@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>
157
@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.
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.
158
</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>
@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>
160
<head>
<title>@ViewBag.Title</title>
</head>
<body>
@RenderBody()
@RenderSection("Scripts", required: false)
</body>
</html>
In this example, @RenderBody() renders the main content of the view,
while @RenderSection(“Scripts”, required: false) attempts to render a section named
“Scripts”. The required: false parameter indicates that the section is optional; if the section
isn’t defined in a view using this layout, the layout will still be rendered without throwing an
error.
RenderSectionAsync
RenderSectionAsync is the asynchronous counterpart to RenderSection. It operates
similarly in that it is used to render sections defined in views, but it does so asynchronously.
This can be useful when the section’s content involves I/O operations, such as database
calls or reading from files, which can be performed asynchronously to improve the
performance of your application. The use of RenderSectionAsync looks similar to
RenderSection, but it requires the await keyword because it is an asynchronous method:
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
@RenderBody()
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Key Differences Between RenderSection and RenderSectionAsync
Methods
RenderSection executes synchronously, while RenderSectionAsync executes
asynchronously. RenderSectionAsync is preferred when the section content involves
asynchronous operations. Using RenderSectionAsync can help prevent the web server
thread from blocking, potentially improving the application’s overall performance.
162
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.
163
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.
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:
166
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,
167
here, the Layout Page, specified in the _ViewStart.cshtml file in the Home sub-folder,
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>
168
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.
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"))
{
169
Layout = "_AdminLayout";
}
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";
}
}
layer code that you frequently reference in your views, you can include these
namespaces in _ViewImports.cshtml to make them universally accessible
without adding @using in each individual view.
Tag Helpers: The @addTagHelper directive allows you to make tag helpers
available across all views. This is useful for frequently used tag helpers, such
as those provided by ASP.NET Core itself or any custom tag helpers you
have developed.
View Layouts: By specifying the @layout directive in _ViewImports.cshtml,
you can define a default layout for all views in the folder. This can be
overridden in specific views if needed.
Note: In this article, I will show you how to use the @using directive in
the ViewImports.cshtml file. We will discuss the rest of the directives in our upcoming
articles.
Example to Understand ViewImports in ASP.NET Core MVC:
Create a class file named Student.cs within the Models folder and then copy and paste the
following code. As you can see, we have created the Student model with five properties.
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
{
171
<html>
<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
173
</td>
</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>
174
</html>
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.
175
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.
176
The settings specified in the _ViewImports file in the Home subfolder will overwrite the
settings specified in the _ViewImports file in the Views folder.
Core 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.
178
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)
179
{
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>
180
<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?
181
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.
182
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>
183
@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>
184
<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
185
{
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);
}
}
}
186
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.
187
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>
188
@{
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>
191
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:
192
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>
193
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
194
to 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:
195
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.
196
@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>
197
<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>
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>
198
model); }. This means the HTML is directly streamed to the output, which can
be more efficient in terms of performance.
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.
200
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
following location- /Views/{Controller Name}/Components/{View
Component Name}/{View Name}
Location 2: If we want to call the view component from the other cshtml file,
then we need to add the view component client-side file at the following
location- /Views/Shared/Components/{View Component Name}/{View
Name}
Location 3: If we are using a view component in Razor pages, then we need
to add the view component client-side file at the following
location- /Pages/Shared/Components/{View Component Name}/{View
Name}
Note: The name for each view component file should be Default.cshtml. But you can also
have other names for your view component client-side file. But the recommended one is
Default.cshtml
How to invoke a View Component from a View File in ASP.NET Core
MVC?
To use a view component, you can invoke it from a view using
the Component.InvokeAsync HTML Helper method, passing the name of the component
and any necessary parameters. View components do not use model binding, so you need
to pass any required data explicitly. We can invoke the view component from a view file by
using the following syntax:
@await Component.InvokeAsync(“Name of view component”, {Anonymous Type
Containing Parameters});
How to invoke a View Component from a View File using Tag helper
ASP.NET Core MVC?
View components can also be invoked using Tag Helper on any view (cshtml) file using the
following syntax.
<vc:[view-component-name]
parameter1=”parameter1 value”
parameter2=”parameter2 value”>
</vc:[view-component-name]>
Example to Understand View Component in ASP.NET Core MVC Web
Application
We want to display top products on the web page using the View Component. Let us see
the step-by-step process to implement this using the View Component. First, create a new
ASP.NET Core Web Application using the Model-View-Controller Project template with the
name ViewComponentInMVC.
Product Model:
Create a class file named Product.cs within the Models folder, and then copy and paste the
following code. This is going to be our model, which will hold the product information.
namespace ViewComponentInMVC.Models
{
201
}
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},
202
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}
};
//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;
203
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
204
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">
205
<tr>
<th>
ProductID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
<tr>
<td>
@product?.ProductID
</td>
<td>
206
@product?.Name
</td>
<td>
@product?.Category
</td>
<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">
207
</div>
With the above changes, run the application, and you should get the following output.
@using ViewComponentInMVC.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, ViewComponentInMVC
@addTagHelper *, ViewComponentInMVC.TagHelpers
208
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.
209
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
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.
As the Razor engine processes the view, it generates dynamic HTML content
by evaluating the embedded C# code and producing corresponding HTML
elements.
Data from the model is inserted into the HTML at the appropriate locations.
Layout Application (Optional):
If a layout is specified for the view, the Razor view engine applies the layout’s
structure around the generated HTML content. Layouts allow you to define a
consistent structure for your pages (e.g., headers, footers, navigation) while
leaving the content area flexible.
Final HTML Output:
The Razor view engine generates the final HTML output, including the
processed C# code, dynamic data, and layout structure.
Response to Client:
The generated HTML content is sent to the client’s web browser as the HTTP
response.
Client Rendering:
The client’s browser receives the HTML response and renders the page,
displaying the dynamic content and UI elements.
The browser also processes any JavaScript or CSS included in the view.
Throughout this process, the Razor view engine manages the seamless integration of C#
code and HTML markup, resulting in a dynamic and interactive user interface. This
approach helps developers maintain clean code separation, allowing them to focus on
building a responsive and feature-rich web application without compromising maintainability.
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
211
{
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; }
}
}
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
};
212
}
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.
Implicit Razor Expressions
Implicit Razor expressions start with @ followed by C# code. In the below example, the
codes @greeting, @DateTime.Now, and @WeekDay are treated as Implicit Razor
expressions. Space is not allowed in the Code expression, as it is used to identify the end of
the expression. The Razor View engine evaluates the expressions, and the result is
inserted in their place.
<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
};
}
<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>
213
Now, run the application, and you should see the following output.
};
}
<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",
216
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.
217
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.
218
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>
}
219
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)
{
220
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 }
};
221
}
<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.
223
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.
226
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.
227
"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.
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
234
and 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
235
{
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" },
236
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())
237
{
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>
238
<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">
239
<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.
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
242
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.
Redirect Results in ASP.NET Core MVC are a type of action result that instructs the
client’s browser to navigate to an external URL or action within the application. They are
used when 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
246
Let us understand how to use ViewResult 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; }
}
}
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);
}
}
}
248
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:
250
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()
251
{
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()
{
252
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,
success: function (viewHTML) {
253
$("#someDiv").html(viewHTML);
},
error: function (errorData) { onError(errorData); }
});
});
</script>
Now, run the application, and you will get the output as expected. In our upcoming articles,
we will discuss how to perform the CRUD operations using jQuery AJAX.
How Do We Prevent the Partial Action Method from being invoked via
normal GET and POST Requests?
Now, you can also access the Details Action Method, which returns a Partial View using
Normal GET and Post Request. Now, we want to restrict this. This means the Details
Action Method should invoked via AJAX Request, not from general GET and Post request.
For this, we need to Create a Custom Attribute, and within the Custom Attribute, we need to
check whether the request is a normal GET Request or POST Request, or it is an AJAX
Request. If it is a normal GET or POST request, we need to return a 404 error; if it is an
AJAX Request, we need to return the data. Let us proceed and see how we can do this.
The X-Requested-With header returns a string indicating whether it’s an Ajax request. An
Ajax request will have this header set to XMLHttpRequest. This header value won’t be
present for normal GET and POST Requests (non-Ajax requests). So, create a Custom
Attribute inheriting from ActionMethodSelectorAttribute. So, add a class file with the
name AjaxOnlyAttribute.cs and then copy and paste the following code into it.
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.Extensions.Primitives;
namespace ActionResultInASPNETCoreMVC.Models
{
public class AjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor
actionDescriptor)
{
if (routeContext.HttpContext.Request.Headers != null &&
routeContext.HttpContext.Request.Headers.ContainsKey("X-Requested-With") &&
routeContext.HttpContext.Request.Headers.TryGetValue("X-Requested-With", out
StringValues requestedWithHeader))
{
if (requestedWithHeader.Contains("XMLHttpRequest"))
254
{
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()
{
Id = ProductId,
255
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:
In this article, I will discuss the JSON Result in ASP.NET Core MVC Web Application with
Examples. Please read our previous article about the Partial View Result in ASP.NET
Core MVC Application.
JSON Result in ASP.NET Core MVC
In ASP.NET Core MVC, a JsonResult represents an HTTP response containing JSON data
(i.e., key-value pairs). It is used when we want to return JSON-formatted data from a
controller action method to the client. JSON (JavaScript Object Notation) is a lightweight
data-interchange format that is easy for humans to read and write and for machines to
parse and generate.
When we return a JsonResult from a controller action, ASP.NET Core MVC serializes the
specified data into JSON format and sends it back to the client as the HTTP response body.
This is commonly used for AJAX requests where the client-side JavaScript code expects to
receive data in JSON format or when building APIs.
Now, if you go to the definition of JosnResult, you will see the following signature. This class
has two constructors, a few properties, and an overriding ExecuteResultAsync method.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People Know
Once serialized, this JSON string is written to the response body, along with
appropriate HTTP headers indicating that the content is JSON.
How Do We Use JsonResult in ASP.NET Core MVC?
In ASP.NET Core MVC, you can use the JsonResult class to return data in JSON format
from your controller actions. First, create a controller action that will return the JSON data
as follows:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public JsonResult Index()
{
var jsonData = new { Name = "Pranaya", ID = 4, DateOfBirth = new DateTime(1988, 02,
29) }
return new JsonResult(jsonData);
}
}
}
Using JsonResult Helper Method:
Alternatively, you can use the Json helper method provided by the Controller class to create
a JsonResult. This method is commonly used to simplify the creation of JSON results:
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public JsonResult Index()
{
var jsonData = new { Name = "Pranaya", ID = 4, DateOfBirth = new DateTime(1988, 02,
29) }
return Json(jsonData);
}
}
}
259
namespace ActionResultInASPNETCoreMVC.Controllers
{
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)
263
{
StatusCode = StatusCodes.Status500InternalServerError // Status code here
};
}
}
}
}
Next, modify the Index.cshtml view as follows:
@{
ViewData["Title"] = "Home Page";
Layout = null;
}
<div>
<table id="tblProducts" class="tblProducts">
<thead>
<tr>
<th align="left" class="productth">ProductID</th>
<th align="left" class="productth">ProductName</th>
<th align="left" class="productth">Descrtption</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#tblProducts tbody tr").remove();
var rawdata = { 'Category': 'Electronics' };
$.ajax({
type: "GET",
url: "/Home/Details/",
264
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.
265
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
{
267
{
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
{
269
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
272
GIF: image/gif
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.
{
public FileResult Index()
{
//Determine File Path
//Directory.GetCurrentDirectory() gets the current working directory of the application,
//\\wwwroot\\PDFFiles\\ is the relative path from the current directory to the file.
string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\PDFFiles\\" +
"Sample.pdf";
//Read File into a Byte Array
//The method System.IO.File.ReadAllBytes is used to load the file from the disk into
memory.
//Reading the file into a byte array is essential for sending the file's content as part of the
HTTP response.
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
//Return the File
//The File method is used to create a FileResult that encapsulates the file data to be sent to
the client.
//This method is called with two parameters:
//fileBytes: The byte array containing the data of the file.
//"application/pdf": The MIME type of the file, which informs the client about the type of file
being sent.
//Specifying "application/pdf" tells the browser or any client that the file is a PDF, which
helps the client to handle the file appropriately.
return File(fileBytes, "application/pdf");
}
}
}
This version of the File method does not include a third parameter for the filename in the
File method call. Without specifying a filename:
Depending on the browser’s behavior and settings, the client (typically a
browser) may use the last part of the URL or generate a generic name for the
downloaded file.
It simplifies scenarios where the actual file name does not need to be
exposed or suggested to the client for any particular reason.
Setting File Download Options:
275
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,
276
//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.
277
be useful for scenarios like handling form submissions, processing data, and then
redirecting the user to a different page.
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
{
279
}
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
280
URLs are mapped to controller actions. By using RedirectToRouteResult, you can take
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();
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?}");
282
app.Run();
}
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");
}
283
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
284
// 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:
285
namespace ActionResultInASPNETCoreMVC.Controllers
// return RedirectToAction("AboutUs");
}
286
}
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} ";
}
287
understood, and accepted the client’s request. These codes typically indicate
that the requested action was successfully completed.
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
289
{
public class HomeController : Controller
{
public IActionResult NotFoundExample()
{
// Return a 404 Not Found response
return new StatusCodeResult(404);
}
public IActionResult CustomStatusCodeExample()
{
// Return a custom status code
return new StatusCodeResult(403);
}
}
}
The NotFoundExample action method returns a 404 (Not Found) response using the
StatusCodeResult class with the status code 404. The CustomStatusCodeExample action
method returns a custom 403 (Forbidden) response using the StatusCodeResult class with
the status code 403. If you visit Home/NotFoundExample, you will get the 404 response we
set in the action method.
Now, if you inspect the request, you will see the server returns a 404 status code, as shown
in the image below.
290
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.
291
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
{
293
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:
295
// 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
{
296
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
298
the appropriate format (JSON, XML, etc.) based on the content negotiation
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 };
299
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);
}
}
}
Why Content Negotiation?
We know that there are three pillars of the internet and they are:
The Resource
The URL
The Representation
The first two (i.e., the resource and the URL) are very straightforward, but the last one (i.e.,
the representation) is a little confusing to understand. Representation is very important in
the modern web. Why? because people are currently not only using Web Applications but
also various types of Mobile applications. The important and interesting fact is that these
devices expect data in various formats.
For example, a few clients want the data in normal HTML, while some want it in normal text
format. Others may need the data in JSON format, and others want it in XML format.
What is Content Negotiation in ASP.NET Core?
Content negotiation is a mechanism used in ASP.NET Core (and other web frameworks)
that allows clients and servers to determine the best way to exchange data. We can also
define Content Negotiation as the process of selecting the best representation for a given
response when multiple representations are available.
One of the REST service standards is that the client should be able to decide in which
format they want the response: XML, JSON, etc. This is called Content Negotiation.
Now, the fact should be clear: Content Negotiation means that the client and the server can
negotiate. It is always impossible to return data in the format requested by the client. That’s
why it is called negotiation, not demand. In such cases, the Web Server will return the data
in the default format. Now, the question that should come to your mind is, how does the
server know or identify in which format the client wants the response? Let us understand
this in detail.
How Content Negotiation Works in ASP.NET Core?
Here’s a basic overview of how content negotiation works in ASP.NET Core:
302
Client Request: When a client (like a web browser, mobile app, or other
server) requests an API endpoint, it can specify its preferred data formats
using the Accept header. For example, a client might
specify application/json if it prefers JSON data or application/xml for XML
data.
Server Response: After processing the request, the server checks
the Accept header and tries to format the response data in one of the
formats 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:
303
using Microsoft.AspNetCore.Mvc;
namespace ActionResultInASPNETCoreMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult ProcessRequest()
{
// 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();
}
}
304
}
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
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.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People Know
@Html.TextBox("firtsname")
You need to remember that several overloaded versions are available for the above
TextBox HTML helper method. To set the value and name, you can use the following
overloaded version of the TextBox helper method.
@Html.TextBox("firtsname", "Pranaya")
At runtime, the above TextBox HTML helper method generates the following HTML
<input id="firtsname" name="firtsname" type="text" value="Pranaya" />
It is also possible to set the HTML attributes of a text box. If you want to do so, you need to
use the following overloaded version of the TextBox HTML helper method.
@Html.TextBox("firtsname", "Pranaya", new { style = "background-color:Red; color:White;
font-weight:bold", title="Please enter your first name" })
Notice that here, we are passing the HTML attributes title and style as an anonymous type
to the TextBox helper method. Some HTML attributes are reserved keywords, such
as readonly, class, etc. If you want to use these attributes within a Helper method, you
must prefix them with the @ symbol, as shown in the example below.
@Html.TextBox("firtsname", "Pranaya", new { @class = "redtextbox", @readonly="true" })
Now, if you want to generate a label, use the Label HTML helper method as follows.
@Html.Label("Name", "Name")
If you want to generate a textbox to enter a password, use the Password HTML Helper
method.
@Html.Password("Password")
Now, if you want to generate a multi-line textbox with 6 rows and 30 columns, then you use
the following TextArea HTML Helper method.
@Html.TextArea("Comments", "", 6, 30, null)
306
If you want to generate a hidden field, use the Hidden HTML Helper method.
@Html.Hidden("Id")
Types of HTML Helpers in ASP.NET Core MVC
There are different types of HTML Helpers available in ASP.NET MVC, such as:
Standard HTML Helpers: These helpers generate HTML elements such as
text boxes, checkboxes, radio buttons, etc. Examples include Html.TextBox(),
Html.BeginForm(), Html.CheckBox(), etc.
Strongly Typed HTML Helpers: These helpers are associated with a specific
data model and provide a type-safe rendering of HTML controls. They use
lambda expressions to refer to model properties directly. Examples include
Html.EditorFor(model => model.PropertyName), Html.DisplayFor(model =>
model.PropertyName), etc.
Custom HTML Helpers: Developers can create their own HTML Helpers to
encapsulate complex or frequently used HTML markup.
Is it mandatory to use HTML Helpers in ASP.NET Core MVC?
No, using HTML Helpers in ASP.NET Core MVC is not mandatory. HTML Helpers simplify
the creation of HTML elements in your views by returning string representations of HTML
elements, making it easier to generate HTML content dynamically.
However, ASP.NET Core MVC also supports Tag Helpers, which are a newer syntax
introduced with ASP.NET Core. Tag Helpers are similar to HTML Helpers but use a more
HTML-like syntax.
Categories of HTML Helpers Methods in ASP.NET Core MVC Application
In ASP.NET Core MVC, HTML Helpers are categorized into various types based on the
type of HTML element they generate. Each type of HTML Helper is designed to simplify the
process of generating specific types of HTML elements within your views. The following are
some common types of HTML Helpers in ASP.NET Core MVC:
Form HTML Helpers:
Form HTML Helpers generate HTML forms and related elements, such as textboxes,
checkboxes, radio buttons, and dropdown lists. These helpers are used to create forms that
can be used to gather user input. The following are the examples:
Html.BeginForm
Html.TextBoxFor
Html.CheckBoxFor
Html.RadioButtonFor
Html.DropDownListFor
Html.TextAreaFor
Link HTML Helpers:
The Link HTML Helpers generate anchor (<a>) tags that create hyperlinks to different
pages within your application. The following are the examples:
Html.ActionLink
Html.RouteLink
Rendering HTML Helpers:
The Rendering HTML Helpers generate raw HTML content or render partial views within
your main view. The following are the examples:
Html.Raw
Html.Partial
307
Html.RenderPartial
List HTML Helpers:
The List HTML Helper generates HTML lists, such as unordered lists (<ul>) and ordered
lists (<ol>). The following is an example:
Html.DisplayFor
Validation HTML Helpers:
The Validation HTML Helpers are used to display validation error messages associated with
model properties. The following is an example:
Html.ValidationMessageFor
HiddenField HTML Helpers:
HiddenField HTML Helpers generate hidden input fields that store data but are not visible to
users.
Example:
Html.HiddenFor
Editor HTML Helpers:
The Editor HTML Helpers generate input fields with specialized editors for specific data
types, such as dates or numbers. The following is an example:
Html.EditorFor
Action HTML Helpers:
The Action HTML Helpers generate URLs for different controller actions. The following is an
example:
Html.Action
Why HTML Helpers in ASP.NET MVC?
HTML Helpers in ASP.NET MVC are utility methods that help generate HTML markup. They
serve several purposes:
Abstraction of HTML: HTML Helpers abstract the low-level details of HTML
markup generation. Instead of manually writing HTML tags in your views, you
can use HTML Helpers to generate them programmatically.
Type Safety: HTML Helpers are strongly typed, meaning they are bound to
specific data types. This ensures type safety during compile time, reducing
the chances of runtime errors.
Code Reusability: By encapsulating common HTML patterns into reusable
methods, HTML Helpers promote code reusability and maintainability. You
can use them across multiple views and share them among different projects.
Intellisense Support: When you use HTML Helpers in your views, you
benefit from Intellisense support in your IDE. This support provides helpful
suggestions and auto-completion, making development faster and more
efficient.
Security: Some HTML Helpers automatically handle the encoding of user
input, helping prevent common security vulnerabilities such as Cross-Site
Scripting (XSS) attacks.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:16 / 03:1110 Sec
}
We will use the above Employee model with TextBox() and TextBoxFor() HTML Helper
methods.
Modifying Home Controller:
Modify the Home Controller as follows. The HomeController is created with one action
method, i.e., the Index action method.
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
return View();
}
TextBox() HTML Helper Method in ASP.NET Core MVC:
310
The Html.TextBox() Helper method creates an element of <input type=”text”> with specified
name, value, and HTML attributes. There are 4 overloaded versions of this Html.TextBox()
Helper method is available, as shown in the image below. The following methods are
loosely typed methods.
Parameters:
htmlHelper: The HTML helper instance that this method extends. It indicates
that it is an extension method that belongs to the IHtmlHelper class.
expression: The name of the form field. Expression name, relative to the
current model.
value: The value of the text input element. If non-null, the value is to be
included in the element.
format: A string that is used to format the input. The format string is used to
format the “value” attribute unless it comes from model binding.
htmlAttributes: An object that contains the HTML attributes for the element.
Returns: It returns a new IHtmlContent containing the <input> element of type text.
Modifying the Index View:
Please modify the Index View of the Home Controller as shown below to use the TextBox
Helper method.
@model HTML_HELPER.Models.Employee
@{
Layout = null;
In the above example, the first parameter is EmployeeName, a property of the Employee
model that will be set as the name and id of the textbox. The second parameter is the value
that we need to display in the textbox, which is null in the above example because the
TextBox() method will automatically display the value of the EmployeeName property of the
Employee model. The third parameter will be set as the class attribute. The HTML attributes
parameter is an object type so that it can be an anonymous object, and the attributes name
will be its properties starting with @ symbol.
You can also specify any name for the textbox. However, it will not be bound to a model.
@Html.TextBox("myTextBox", "This is value", new { @class = "form-control" })
It will produce the following HTML
<input class=”form-control” id=”myTextBox” name=”myTextBox” type=”text”
value=”This is value” />
TextBoxFor() HTML Helper Method in ASP.NET Core MVC Application:
The TextBoxFor() HTML helper is a strongly typed HTML helper method in ASP.NET Core
MVC that generates a text input element for a form. This helper method binds a model
property to a text box, enabling the framework to handle data display, data posting, and
validation feedback for the associated property automatically. The TextBoxFor() HTML
Helper Method has 3 overloaded versions available in ASP.NET Core MVC, as shown in
the image below.
Parameters:
htmlHelper: The IHtmlHelper instance that this method extends.
expression: An expression to be evaluated against the current model.
format: A string that is used to format the input. The format string is used to
format the expression value in the “value” attribute.
htmlAttributes: An object that contains the HTML attributes for the element.
Type parameters:
TModel: The type of the model.
TResult: The type of expression results.
Returns: It returns a new IHtmlContent containing the <input> element whose type attribute
is set to “text”.
Example to understand the TextBoxFor() HTML Helper Method:
The Html.TextBoxFor method is used with a lambda expression that specifies the model
property to which to bind. This approach is strongly typed and helps prevent errors due to
typos in property names. Copy and paste the following code into Index.cshtml view.
@model HTML_HELPER.Models.Employee
Here,
model => model.EmployeeName: A lambda expression that specifies the
property of the model to which this TextBox is bound.
new { @class = “form-control” }: Similar to the Html.TextBox example sets
the HTML attributes for the TextBox.
Run the application and inspect the element, and you will see that it will produce the
following HTML
<input class=”form-control” id=”EmployeeName” name=”EmployeeName”
type=”text” value=”” />
In the above example, the first parameter in TextBoxFor() HTML Helper Method is a lambda
expression that specifies the EmployeeName property of the Model object to bind with the
textbox. It generates an input-type text element with id and name property, and the
property’s value is set to EmployeeName. The value attribute will be set to the value of the
EmployeeName property of the Model Object.
What are the Differences Between Html.TextBox and Html.TextBoxFor in
ASP.NET Core MVC?
In ASP.NET Core MVC, both Html.TextBox and Html.TextBoxFor are HTML helpers that
generate an HTML <input type=”text”> element. The following are the key differences
between Html.TextBox and Html.TextBoxFor:
Syntax and Usage
TextBox: This helper is used to specify the name of the form field as a string.
It does not provide strong typing and compile-time checking since the field
name is specified as a string. Syntax: @Html.TextBox(“fieldName”,
(object)value, (object)htmlAttributes).
TextBoxFor: This helper uses a lambda expression to specify the form field,
offering strong typing and compile-time checking. It is tied directly to a model
property. Syntax: @Html.TextBoxFor(model => model.Property,
(object)htmlAttributes).
Strong Typing
TextBox is not strongly typed. The input field’s name is provided as a
string, which means you lose the benefits of compile-time checking. Mistyping
the field name results in a runtime error, not a compile-time error.
TextBoxFor is strongly typed. It uses a lambda expression to refer to the
model property directly, ensuring that any changes to the property name are
reflected at compile time, thus reducing the risk of errors.
Model Binding
TextBox requires manual association with model properties. Since it uses a
string to identify the field, you need to ensure it matches the model property
name so it binds correctly.
TextBoxFor automatically binds to the model property specified in the lambda
expression, making it easier to maintain and refactor code as the model
changes.
IntelliSense and Refactoring
TextBox does not support IntelliSense for the field names since they are just
strings. Refactoring tools will not update these strings if the associated model
property changes.
313
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:16 / 03:1110 Sec
In this example, the DropDownList allows users to select a country from the list. When a
user selects an option, the value of the <select> element (accessible through JavaScript or
on the server side after form submission) becomes the value of the selected <option>.
How Do We Create DropDownList using HTML Helper in ASP.NET Core
MVC?
To create a DropDownList using the HTML Helper Method in the ASP.NET Core MVC
Application, we need to use the DropDownList Helper method. In ASP.NET Core MVC, the
DropDownList HTML Helper generates an <select> element representing a dropdown list in
an HTML form. We can use two different types of DropDownList Helper methods to
generate a textbox in a Razor view. These two extension methods are DropDownList() and
DropDownListFor().
The Html.DropDownList method is used when you want to specify the name of the form
field manually, while Html.DropDownListFor is used with model properties, providing a
strongly typed approach. That means the DropDownList() HTML Helper method is loosely
typed, whereas the DropDownList() HTML Helper method is strongly typed.
What is DropDownList HTML Helper in ASP.NET Core MVC?
The DropDownList HTML Helper in ASP.NET Core MVC is a server-side helper method
that dynamically generates a dropdown list (HTML <select> element) on a web page.
When using the DropDownList HTML Helper, developers can specify the data source for
the dropdown list, the field to be displayed to the user, and the field that represents the
value of each option. This makes it straightforward to bind the dropdown list to data models
or collections, such as lists or enumerations, and to automatically select a value based on
the model’s current state.
Example to Understand DropDownList HTML Helper Method in ASP.NET
Core
A DropDownList in an ASP.NET Core MVC application is nothing but a collection of
SelectListItem objects. Depending on your business requirement, you may either hard code
the values or retrieve the values from a database table. In this article, I am going to discuss
both approaches. First, we will discuss creating the DropDownList using the hard-coded
values and then see how to create the DropDownList with the values from a database.
The following code will generate a department dropdown list. The first item in the drop-down
list will be “Select Department”. Here, we have used the Selected property to true for the
IT element, so elements will be selected by default when the page loads.
@Html.DropDownList("Departments", new List<SelectListItem>
{
new SelectListItem { Text = "IT", Value = "1", Selected=true},
new SelectListItem { Text = "HR", Value = "2"},
new SelectListItem { Text = "Payroll", Value = "3"}
}, "Select Department")
The downside of hard-coding the DropDownList value within the code itself is that if we
have to add or remove departments from the DropDownList, the code must be modified
every time.
How do you set the Dropdown list values from the database in the
ASP.NET Core MVC?
315
Most of the time, or in real-time applications, we generally get the data from a database. To
understand this, let’s create a Department Class and then populate the values within the
controller. First, add a class file named Department.cs within the Models folder and then
copy and paste the following code into it.
namespace HTML_HELPER.Models
{
public class Department
{
public int Id { get; set; }
public string Name { get; set; } = null!;
}
}
Then, modify the Home Controller as follows. We store the list of departments in the
ViewBag to pass it from the controller action method to the index view.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
//Get the data from the database
//Here we are creating Department list
List<Department> ListDepartments = new List<Department>()
{
new Department() {Id = 1, Name="IT" },
new Department() {Id = 2, Name="HR" },
new Department() {Id = 3, Name="Payroll" },
};
// Retrieve departments and build SelectList
ViewBag.Departments = new SelectList(ListDepartments, "Id", "Name");
return View();
}
316
}
}
You can also do the same thing in the following way:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>()
{
new SelectListItem { Text = "IT", Value = "1" },
new SelectListItem { Text = "HR", Value = "2" },
new SelectListItem { Text = "Payroll", Value = "2" }
};
ViewBag.Departments = items;
return View();
}
}
}
Next, modify the Index.cshtml view as follows. In the Index view, access the Department list
from ViewBag.
@Html.DropDownList("Departments", @ViewBag.Departments as List<SelectListItem>,
"Select Department", new { @class = "form-control"})
In the above example, the first parameter is the property name for which we want to display
the list of items. The second parameter is the list of values that will be displayed within the
DropDownList. Here, we have used the ViewBag mechanism to get the department values.
The third parameter is the label, which is nothing but the first item in the drop-down list, and
the fourth parameter is for the HTML attributes like CSS to be applied on the drop-down list.
If you inspect the dropdown list, the code below will be generated.
<select class="form-control" id="Departments" name="Departments"><option
value="">Select Department</option>
<option value="1">IT</option>
317
<option value="2">HR</option>
<option value="2">Payroll</option>
</select>
How Do We Use Enum to set the Dropdown list values in the ASP.NET
Core MVC Application?
Let’s see how to use Enum to set the Dropdown list values. In this example, we will set the
Gender Values from the enum. So, create a class file named Gender.cs and add the
following Gender enum.
namespace HTML_HELPER.Models
{
public enum Gender
{
Male,
Female
}
}
Copy and paste the following code into the index view.
@using HTML_HELPER.Models
@{
Layout = null;
}
@Html.DropDownList("EmployeeGender",
new SelectList(Enum.GetValues(typeof(Gender))),
"Select Gender",
new { @class = "form-control" })
In the above example, the first parameter is the property name for which we want to display
the list items. The second parameter is the list of values, which will be displayed in the drop-
down list. We have used Enum methods to get Gender enum values. The third parameter is
the label, which will be the first list item in the drop-down list, and the fourth parameter is for
the HTML attributes like CSS to be applied on the dropdown list.
When we run the application, it will generate the following HTML
<select class="form-control" id="EmployeeGender" name="EmployeeGender"><option
value="">Select Gender</option>
<option>Male</option>
<option>Female</option>
318
</select>
DropDownListFor HTML Helper in ASP.NET Core MVC Application:
The DropDownListFor() is an HTML helper method in ASP.NET Core MVC that is used to
generate a <select> element (a drop-down list) for a web page from a model property. This
helper is strongly typed, meaning it is bound to a specific model property and helps display
a list of options the user can select from. The selected value from the drop-down list can
then be posted back to the server as part of the model during form submission. The
following is a basic example of how it might be used in a view:
@Html.DropDownListFor(model => model.SelectedItemId, new
SelectList(Model.Items, “Value”, “Text”))
In this example:
model => model.SelectedItemId specifies the model property to which the
drop-down list is bound. This property holds the selected item’s value.
new SelectList(Model.Items, “Value”, “Text”) creates a new SelectList
object where Model.Items are the collection of items you want to display in
the drop-down. “Value” and “Text” specify the names of the properties in the
Model.Items that contain the values and the display texts of the items,
respectively.
Example to Understand DropDownListFor HTML Helper Method
We will use the following models to understand the DropDownListFor HTML Helper in
ASP.NET Core MVC Application.
Employee.cs
namespace HTML_HELPER.Models
{
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; } = null!;
public string Gender { get; set; } = null!;
public int DepartmentID { get; set; }
}
}
Department.cs
namespace HTML_HELPER.Models
{
public class Department
{
public int Id { get; set; }
public string Name { get; set; } = null!;
319
}
}
Gender.cs
namespace HTML_HELPER.Models
{
public enum Gender
{
Male,
Female
}
}
Modify the HomeController as shown below.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
//Let’s create list department for dropdownlist
List<Department> ListDepartments = new List<Department>()
{
new Department() {Id = 1, Name="IT" },
new Department() {Id = 2, Name="HR" },
new Department() {Id = 3, Name="Payroll" },
};
ViewBag.Departments = ListDepartments;
//let’s create one employee
Employee emp = new Employee()
{
EmployeeId = 1,
320
EmployeeName = "Pranaya",
Gender = "Male",
DepartmentID = 2
};
//Pass that employee to the view
return View(emp);
}
}
}
Modify the Index.cshtml file as shown below:
@using HTML_HELPER.Models
@model Employee
@{
ViewData["Title"] = "Home Page";
Layout = null;
}
@Html.DropDownListFor(emp => emp.Gender,
new SelectList(Enum.GetValues(typeof(Gender))),
"Select Gender",
new { @class = "form-control" })
@Html.DropDownListFor(emp => emp.DepartmentID,
new SelectList(ViewBag.Departments, "Id", "Name"),
"Select Department",
new { @class = "form-control" })
In the above example, the first parameter in the DropDownListFor() HTML Helper method is
a lambda expression that specifies the model property to be bound with the select element.
We have specified the Gender property of the enum type and DepartmentID property. The
second parameter specifies the items to show in the dropdown list using SelectList. The
third parameter is the option Label, which will be the first item of the drop-down list.
Using DropDownList, if you want to show the selected Department of that particular
employee, then you need to use the following code.
@Html.DropDownList("DepartmentID",
new SelectList(ViewBag.Departments, "Id", "Name", Model.DepartmentID),
"Select Department",
new { @class = "form-control" })
321
User Interface: Visually, a radio button appears as a small circle that can be
filled or surrounded by a dot when selected. Unselected radio buttons are
empty circles.
State Indicator: When selected, a radio button typically displays a small dot
or circle inside it to indicate the chosen option.
HTML Structure: In HTML, a radio button is represented by an <input>
element with a type attribute set to “radio”. Each radio button within a group
should have the same name attribute and a unique value attribute.
Use Cases: Radio buttons are commonly used when users need to make a
single choice from a predefined set of options, such as selecting a gender,
choosing a payment method, or indicating a preference.
Here’s a simple HTML example that demonstrates the use of radio buttons:
<form>
<p>Select your age range:</p>
<input type="radio" id="age1" name="age" value="under-18">
<label for="age1">Under 18</label><br>
<input type="radio" id="age2" name="age" value="18-30">
<label for="age2">18-30</label><br>
<input type="radio" id="age3" name="age" value="31-45">
<label for="age3">31-45</label><br>
<input type="radio" id="age4" name="age" value="over-45">
<label for="age4">Over 45</label>
</form>
In this example, users can select their age range from the provided options. Because all
radio buttons share the same name attribute (age), only one of these options can be
selected at a time, ensuring a clear and straightforward selection process.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
How Do We Create Radio Buttons Using HTML Helper in ASP.NET Core
MVC?
To create a Radio button using the HTML Helper Method in the ASP.NET Core MVC
Application, we need to use the RadioButton Helper method. In the ASP.NET Core MVC,
we can use two different types of RadioButton Helper methods to generate a RadioButton in
a Razor view. These two extension methods are RadioButton() and RadioButtonFor().
The Html.RadioButton method is used when you want to specify the name of the form field
manually, while Html.RadioButtonFor is used with model properties, providing a strongly
typed approach. That means the RadioButton() HTML Helper method is loosely typed,
whereas the RadioButtonFor() HTML Helper method is strongly typed.
What is RadioButton HTML Helper in ASP.NET Core MVC?
The @Html.RadioButton() HTML Helper in ASP.NET Core MVC is a server-side helper
method to generate HTML radio button input elements for your web forms. The RadioButton
323
helper is specifically designed to create radio buttons that allow users to select one option
from a group of choices.
The basic syntax of the @Html.RadioButton() helper method is as
follows: @Html.RadioButton(string name, object value, bool isChecked, object
htmlAttributes)
Here,
name: The name attribute of the generated radio button, which is used to
group together multiple radio buttons. Only one radio button in the same
group (i.e., having the same name) can be selected at a time.
value: The value attribute for the radio button, which represents the value
that will be submitted if this radio button is selected.
isChecked: A boolean value indicating whether the radio button should be
initially selected (checked) when the page loads.
htmlAttributes: An anonymous object that can be used to set HTML
attributes for the radio button, such as class, style, id, etc.
Example to Understand RadioButton HTML Helper Method in ASP.NET
MVC:
The Html.RadioButton() HTML Helper method in ASP.NET Core MVC Application is used to
create a radio button element with a specified name, isChecked boolean property, and the
HTML attributes. The Html.RadioButton() HTML Helper method is loosely typed.
Male: @Html.RadioButton("Gender", "Male")
Female: @Html.RadioButton("Gender", "Female")
If you inspect the HTML, then you will see the following HTML
Male: <input id="Gender" name="Gender" type="radio" value="Male" />
Female: <input id="Gender" name="Gender" type="radio" value="Female" />
In the above example, we have created two radio buttons, Male and Female, for the Gender
property. The first parameter is the group name. The point that you need to remember is
that you need to give the same name to both the radio buttons. The second parameter is
the value of the radio button, which will be sent to the server when the respective radio
button is checked. That means if the Male radio button is selected, the string value Male will
be assigned to a model property named Gender and submitted to the server.
What is RadioButtonFor HTML Helper in ASP.NET Core MVC?
The RadioButtonFor() HTML helper in ASP.NET Core MVC is a server-side helper that
generates an HTML radio button input element for a specified model property. This helper
binds a radio button to a model property in your view model, ensuring that the radio button’s
state reflects the current value of the model property when rendering the page, and also
facilitates the process of updating this property when the form is submitted back to the
server.
The RadioButtonFor() helper is strongly typed, meaning it is bound to a specific property of
a model passed to your view from a controller. This binding is established through a lambda
expression, making it more resistant to errors that can occur due to renaming properties in
your model because these changes are often detected at compile time rather than at
runtime.
Here’s a basic syntax example of using RadioButtonFor(): @Html.RadioButtonFor(model
=> model.PropertyName, value, htmlAttributes)
324
Here,
model => model.PropertyName: A lambda expression that specifies the
model property to bind to.
value: The value to be assigned to the radio button when selected.
htmlAttributes: (Optional) An object containing HTML attributes to set for the
element.
Example to Understand RadioButtonFor HTML Helper in ASP.NET Core
MVC
To understand this, let’s create a new model. Right-click on the Models folder and then add
two class files named Company.cs and Department.cs. Copy and paste the following
code once you create the class files.
Department.cs
namespace HTML_HELPER.Models
{
public class Department
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Company.cs
namespace HTML_HELPER.Models
{
public class Company
{
public int SelectedDepartment { get; set; }
public List<Department> Departments()
{
List<Department> ListDepartments = new List<Department>()
{
new Department() {Id = 1, Name="IT" },
new Department() {Id = 2, Name="HR" },
new Department() {Id = 3, Name="Manager" },
};
return ListDepartments;
}
}
325
}
Modifying Home Controller:
Next, modify the Home Controller as follows.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
Company company = new Company();
//company.SelectedDepartment = 2;
return View(company);
}
[HttpPost]
public string Index(Company company)
{
if (company.SelectedDepartment <= 0)
{
return "You did not select any department";
}
else
{
return "You selected department with ID = " + company.SelectedDepartment;
}
}
}
}
Modifying Index Views:
Next, modify the Index.cshtml view as follows.
@model HTML_HELPER.Models.Company
@{
326
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
foreach (var department in Model.Departments())
{
@Html.RadioButtonFor(m => m.SelectedDepartment, department.Id)
@department.Name
}
<br />
<br />
<input type="submit" value="Submit" />
}
In the above example, the first parameter in the RadioButtonFor() HTML Helper method is a
lambda expression that specifies the model property to be bound with the RadioButton
element. We have created radio buttons for the SelectedDepartment property in the above
example. So, it generates three <input type=”radio”> elements with id and name set to
property name SelectedDepartment. The second parameter is the value that will be sent to
the server when the form is submitted.
Note: The RadioButtonFor method takes two arguments: an expression to define the model
property and the radio button’s value. When the form is submitted, the selected value will be
bound to the specified model property.
Testing the Application:
Run the application and inspect the HTML. Once you inspect the HTML, you will see that
the following HTML codes are generated by the RadioButton helper method.
<input id="SelectedDepartment" name="SelectedDepartment" type="radio" value="1" />IT
<input id="SelectedDepartment" name="SelectedDepartment" type="radio" value="2"
/>HR
<input id="SelectedDepartment" name="SelectedDepartment" type="radio" value="3"
/>Manager
What are the Differences Between Html.RadioButton and
Html.RadioButtonFor in ASP.NET Core MVC?
In ASP.NET Core MVC, the Html.RadioButton and Html.RadioButtonFor helper methods
are used to generate radio button controls in a form that is tied to model properties.
Understanding the differences between these two methods can help you choose the right
one for your scenario. Here’s a breakdown of their main differences:
Purpose and Usage
327
<label>
Music
</label>
<label>
Books
</label>
<label>
Sports
</label>
</form>
329
In this example, users can select their interests among music, books, and sports. The form
will send the values of the selected interests to the server when submitted. CheckBoxes are
useful in web applications for various purposes, such as settings that can be turned on or
off independently, multiple selections from a list of options, and features like agreeing to
terms and conditions.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
Subscribe to Newsletter
It will generate the following HTML Element.
330
}
Next, modify the Home Controller as follows:
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
331
[HttpGet]
model.IsSubscribed = false;
return View(model);
[HttpPost]
if (model.IsSubscribed)
else
}
Next, modify the Index.cshtml file as follows:
@model HTML_HELPER.Models.NewsLetter
@{
332
ViewBag.Title = "Index";
Layout = null;
<h2>Index</h2>
@using (Html.BeginForm())
<br/><br/>
}
In this example, IsSubscribed is a boolean property in the model that will hold the
checked/unchecked state of the checkbox. The CheckBoxFor method takes an expression
as an argument to define the model property. When the form is submitted, the
checked/unchecked state will be bound to the specified model property.
Now, run the application and click the Submit button without checking the check box. Notice
that you are getting a message stating You Have Not Subscribed to our Newsletter. On the
other hand, if you check the check box and then click the Submit button, you will see the
You Subscribed to our Newsletter message.
Generating Multiple Check Boxes using CheckBoxFor Helper Method:
In ASP.NET Core MVC, you can generate multiple checkboxes using the CheckBoxFor
helper method by binding them to your model’s collection property. Here’s a step-by-step
guide to demonstrate how to achieve this: We want to create the interfaces with the
following checkboxes.
333
Our requirement is when we select the checkboxes and click on the submit button. All the
selected checkbox values should display as “You selected – Checkbox Values,” if we
don’t select any checkbox, then the message should be “You have not selected any City”
displayed.
First, create a class file named City.cs and copy and paste the following code into it.
namespace HTML_HELPER.Models
}
Next, modify the Home Controller as follows:
using HTML_HELPER.Models;
334
using Microsoft.AspNetCore.Mvc;
using System.Text;
namespace HTML_HELPER.Controllers
[HttpGet]
};
return View(CityList);
[HttpPost]
{
335
else
if (city.IsSelected)
sb.Remove(sb.ToString().LastIndexOf(","), 1);
return sb.ToString();
}
Next, modify the Index.cshtml file as follows:
In the below view, CheckBoxFor is used inside a loop to render checkboxes for each item in
the collection. A hidden field is also used to maintain each item’s ID. When the form is
submitted, the selected checkboxes are sent to the corresponding action method.
@model List<HTML_HELPER.Models.City>
336
@{
ViewBag.Title = "Index";
Layout = null;
@using (Html.BeginForm())
<table>
<tr>
<td>
</td>
<td>
</td>
</tr>
</table>
}
Note:
337
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:11 / 03:1110 Sec
What is ListBoxFor HTML Helper in ASP.NET Core MVC?
339
The ListBoxFor HTML helper in ASP.NET Core MVC is a server-side helper used to
generate a <select> HTML element with the “multiple” attribute, allowing users to select
multiple options from a list. The ListBoxFor helper is specifically designed to work with
model properties. It is strongly typed, meaning it binds directly to model properties in your
MVC application, ensuring compile-time checking of the property names you are binding to,
which reduces the risk of errors.
Syntax: @Html.ListBoxFor(model => model.SelectedIds, new
SelectList(Model.AvailableOptions, “Value”, “Text”))
Here,
model => model.SelectedIds indicates the model property to which the
ListBoxFor will bind. This property should be a collection that will hold the
values of the selected options.
new SelectList(Model.AvailableOptions, “Value”, “Text”) is used to
generate the list items for the <select> element. Model.AvailableOptions is a
collection within your model that holds the options to be displayed. “Value”
and “Text” specify the property names in AvailableOptions that will be used
for the option values and display texts, respectively.
List Box Example using ListBoxFor HTML Helper in ASP.NET Core MVC:
You can use the ListBoxFor HTML Helper Method in the ASP.NET Core MVC Application to
generate a list box. This method generates an HTML <select> element with <option>
elements representing the available options. We need to generate the following list box.
We want to allow the user to select one or more cities from the ListBox. Once the user
selects the cities and clicks on the Submit button, we need to display the names of the
selected cities separated by a comma. If the user doesn’t select any city and clicks on the
Submit button, then the No Cities are Selected message should be displayed.
Creating Models:
First, you need a model that contains a list of items to populate the ListBox and possibly a
property to hold the selected item(s). First, create a class file named City.cs and copy and
paste the following code into it.
namespace HTML_HELPER.Models
340
{
public class City
{
public int CityId { get; set; }
public string? CityName { get; set; }
public bool IsSelected { get; set; }
}
}
Next, we need to create a View Model. In ASP.NET Core MVC, view models are nothing
but a mechanism to shuttle data between the controller and the view. To create the View
Model, right-click on the Models folder and add a new class file named CitiesViewModel.
Once you create the CitiesViewModel, copy and paste the following code. This class is
going to be the model for our view.
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Models
{
public class CitiesViewModel
{
public IEnumerable<int>? SelectedCities { get; set; }
public IEnumerable<SelectListItem>? Cities { get; set; }
}
}
Next, we need to modify the HomeController as follows:
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
private List<City> CityList;
public HomeController()
{
341
{
if (selectedCities == null)
{
return "No Cities Selected";
}
else
{
//First Fetch the Names of the Cities Selected
var CityNames = CityList
.Where(t => selectedCities.Contains(t.CityId))
.Select(item => item.CityName).ToList();
StringBuilder sb = new StringBuilder();
sb.Append("Your Selected City Names - " + string.Join(",", CityNames));
return sb.ToString();
}
}
}
}
Next, modify the Index.cshtml view file as follows.
@model HTML_HELPER.Models.CitiesViewModel
@{
ViewBag.Title = "Index";
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.ListBoxFor(m => m.SelectedCities, Model.Cities, new { size = 7 })
<br />
<input type="submit" value="Submit" />
}
</div>
343
Note: In order to select multiple items from the list box, you need to hold down the CTRL
Key. Run the application and see if everything is working as expected.
What is ListBox HTML Helper in ASP.NET Core MVC?
The ListBox HTML Helper in ASP.NET Core MVC is a server-side helper used to generate
a list box (a <select> element with the “multiple” attribute) on a web page. To use the
ListBox HTML Helper, you generally need to specify the name of the form field and a
selection list (usually provided as SelectList or IEnumerable<SelectListItem>). Optionally,
you can also include HTML attributes to customize the appearance or behavior of the list
box.
Syntax: @Html.ListBox(“MyListBox”, Model.MySelectListItems, new { @class = “my-
custom-class” })
Here:
“MyListBox” is the name of the form field.
Model.MySelectListItems is the collection that populates the list box, where
MySelectListItems is typically a property of the model passed to the view
containing a collection of SelectListItem objects.
new { @class = “my-custom-class” } represents HTML attributes to add to
the generated <select> element, such as a CSS class.
ListBox Example using ListBox HTML Helper in ASP.NET Core MVC:
Let us understand How we can use the ListBox HTML Helper in ASP.NET Core MVC
Application, which is not a strongly typed HTML helper. We are going to do the same
example using ListBox HTML Helper. So, modify the Home Controller class as follows.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
private List<City> CityList;
public HomeController()
{
CityList = new List<City>()
{
new City(){ CityId = 1, CityName = "London", IsSelected = false },
new City(){ CityId = 2, CityName = "New York", IsSelected = false },
new City(){ CityId = 3, CityName = "Sydney", IsSelected = false },
new City(){ CityId = 4, CityName = "Mumbai", IsSelected = false },
new City(){ CityId = 5, CityName = "Cambridge", IsSelected = false },
344
{
//First Fetch the Names of the Cities Selected
var CityNames = CityList
.Where(t => selectedCities.Contains(t.CityId))
.Select(item => item.CityName).ToList();
StringBuilder sb = new StringBuilder();
sb.Append("Your Selected City Names - " + string.Join(",", CityNames));
return sb.ToString();
}
}
}
}
Next, modify the Index.cshtml file as follows:
@{
ViewBag.Title = "Index";
CitiesViewModel citiesViewModel = ViewBag.CitiesViewModel;
}
<div style="font-family:Arial">
<h2>Index</h2>
@using (Html.BeginForm())
{
@*@Html.ListBox("selectedCities", citiesViewModel.Cities,
citiesViewModel.SelectedCities)*@
@Html.ListBox("selectedCities", citiesViewModel.Cities, new { size = 7 })
<br />
<input type="submit" value="Submit" />
}
</div>
With the above changes in place, run the application, and you should get the expected
output.
What are the Differences Between ListBox and ListBoxFor in ASP.NET
Core MVC?
In ASP.NET Core MVC, ListBox and ListBoxFor are HTML helper methods used to create a
list box (a select element) that allows users to select one or more items. While both serve
346
similar purposes, they differ primarily in their usage syntax and how they bind to model
properties. Here’s a breakdown of the differences:
ListBox:
Usage: It creates a list box without strongly typed model binding. The name
parameter corresponds to the name of the form field, and it collects the
selected value(s) upon form submission.
Flexibility: Since it is not strongly tied to a model property, ListBox offers
more flexibility in scenarios where you don’t have a direct model property to
bind or when working with dynamic views.
Binding: The binding is manual. You must ensure that the selected values
match those in your model or data source, especially in postback scenarios.
ListBoxFor:
Usage: It is used for strongly typed model binding. The expression parameter
is a lambda expression that identifies the model property to which to bind.
This approach integrates tightly with the model validation and binding
features of ASP.NET Core MVC.
Strong Typing: ListBoxFor ensures compile-time checking of the expression
passed to it, reducing the risk of errors due to mistyped property names.
Model Binding: It automatically binds the selected value(s) to the specified
model property. This is particularly useful for scenarios involving form
submissions and model validation, as it simplifies the process of capturing
and validating user input.
Choosing Between ListBox and ListBoxFor:
The choice between ListBox and ListBoxFor depends on the specific requirements of your
application:
Use ListBox when you need a dropdown list that is not directly tied to a model
property or when working in a dynamically generated UI where model
properties might not be known at compile time.
Use ListBoxFor when working with a strongly typed model where you want to
take advantage of MVC’s model binding and validation features. It’s
particularly useful in forms where capturing user input directly into a model is
desired.
Editor HTML Helper in ASP.NET Core MVC
In this article, I will discuss How to Use Editor HTML Helper in ASP.NET Core
MVC Application to generate input HTML elements. Please read our previous article, where
we discussed How to Generate a List Box using List Box HTML Helper in ASP.NET
Core MVC Application.
Editor HTML Helper in ASP.NET Core MVC
As of now, we have seen and used different types of HTML Helper methods to generate
different types of HTML elements in ASP.NET Core MVC applications. In ASP.NET Core
MVC, the Editor HTML Helper is a method used to generate an HTML input element based
on the data type and metadata of a model property. It is commonly used within views to
render input fields for properties of a model object.
Data Types and Its Equivalent HTML Elements:
The Editor HTML Helper automatically selects the appropriate editor template based on the
data type of the rendered property. It uses the model metadata to determine how to
generate the input field, taking into account factors such as data type, display format,
347
validation attributes, etc. The following diagram lists the HTML element that is created for
each data type by the Editor() or EditorFor() method.
Conquering the clouds on a journey to Ta Xua with the team - Road Trip Vietnam Team
- Nếm TV00:05 / 02:5410 Sec
Editor HTML Helper Method in ASP.NET Core MVC:
Editor is a generic method that creates an input element for the specified model property. It
is used when you want to manually specify the type of input element or provide additional
attributes. The Editor HTML Helper method requires a string expression as a parameter to
specify the property name. This Editor() extension method creates the input HTML element
based on the data type of the specified expression. Syntax:
@Html.Editor(“PropertyName”)
Let’s understand how to use Editor HTML Helper in an ASP.NET Core MVC Application
with one example. First, create a class file named Employee.cs within the Models folder
and copy and paste the following code into it.
namespace HTML_HELPER.Models
{
public class Employee
{
public int EmployeeId { get; set; }
public string? Name { get; set; }
public Gender Gender { get; set; }
public int Age { get; set; }
public bool IsNewlyEnrolled { get; set; }
public DateTime? DOB { get; set; }
}
public enum Gender
{
Male,
348
Female
}
}
Next, modify the HomeController as follows.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
Employee emp = new Employee()
{
EmployeeId = 101,
Name = "Pranaya",
Gender = Gender.Male,
Age = 30,
IsNewlyEnrolled = true,
DOB = Convert.ToDateTime("29-02-1988")
};
return View(emp);
}
}
}
Next, modify the Index.cshtml view file as follows.
@using HTML_HELPER.Models
@model Employee
<table>
<tr>
<td>EmployeeId</td>
<td>@Html.Editor("EmployeeId")</td>
</tr>
349
<tr>
<td>Name</td>
<td>@Html.Editor("Name")</td>
</tr>
<tr>
<td>Gender</td>
<td>@Html.Editor("Gender")</td>
</tr>
<tr>
<td>Age</td>
<td>@Html.Editor("Age")</td>
</tr>
<tr>
<td>IsNewlyEnrolled</td>
<td>@Html.Editor("IsNewlyEnrolled")</td>
</tr>
<tr>
<td>DOB</td>
<td>@Html.Editor("DOB")</td>
</tr>
</table>
Now, run the application; it will give you the following output.
350
In the above example, we have specified the property names of the Employee model. So,
the Editor HTML Helper method creates the appropriate input elements based on the
datatype of Employee model properties, as shown in the above image.
EditorFor HTML Helper Method in ASP.NET Core MVC:
EditorFor is a strongly typed method that generates an input element based on the type of
the model property. It infers the appropriate input type based on the data type of the
property. It is typically used when you want to use the model metadata or apply custom
display/editor templates. Example: @Html.EditorFor(model => model.PropertyName)
The EditorFor HTML Helper method is a strongly typed helper method. As it is a strongly
typed method, we must use a lambda expression to specify the name. Let us understand
this with an example. Please modify the index.cshtml view as shown below to use the
EditorFor extension method
@using HTML_HELPER.Models
@model Employee
<br />
<table>
<tr>
<td>EmployeeId</td>
<td>@Html.EditorFor(emp => emp.EmployeeId)</td>
</tr>
<tr>
<td>Name</td>
<td>@Html.EditorFor(emp => emp.Name)</td>
</tr>
<tr>
<td>Gender</td>
<td>@Html.EditorFor(emp => emp.Gender)</td>
</tr>
<tr>
<td>Age</td>
<td>@Html.EditorFor(emp => emp.Age)</td>
</tr>
<tr>
<td>IsNewlyEnrolled</td>
<td>@Html.EditorFor(emp => emp.IsNewlyEnrolled)</td>
</tr>
<tr>
351
<td>DOB</td>
<td>@Html.EditorFor(emp => emp.DOB)</td>
</tr>
</table>
In the above example, we specified the property name using the lambda expression. The
result is the same whether you use the Editor() or the EditorFor() extension method. Now,
run the application; it will give you the same output.
What are the Differences Between Editor and EditorFor in ASP.NET Core
MVC?
In ASP.NET Core MVC, Editor, and EditorFor are HTML helper methods used to render
form fields for model properties in a Razor view. However, they differ in how they are used
and the level of control they provide.
Usage:
Editor: This is a static method available in the HtmlHelper class. It’s generally
used when you want to render a form field for a specific property of a model
and don’t need to specify much about the rendering behavior.
EditorFor: This is a strongly typed method based on the model’s metadata.
It’s used when you want to render a form field based on a property’s data
type and possibly use additional attributes specified in the model (like data
annotations).
Customization:
Editor: It provides less customization as it directly renders an input field
based on the type of the property. You have to handle additional
customization manually.
EditorFor: It provides more customization options. It renders the input field
based on the property’s data type and uses model metadata for additional
attributes like display name, validation attributes, etc. You can also create
custom editor templates for specific data or property types to customize
rendering further.
Strongly Typed:
EditorFor is strongly typed, meaning it relies on the model type and its
metadata to render form fields. This helps catch errors at compile-time and
provides better IntelliSense support in Razor views.
Editor is not strongly typed, so you need to manually specify the property
name or use a magic string to refer to model properties. This can lead to
runtime errors if the property name is mistyped.
352
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:03 / 03:1110 Sec
<label for=”password”>Password:</label>: This is a label element that is
associated with the password input field. It helps improve accessibility by
providing a text description for the input.
<input type=”password” id=”password” name=”password”>: This is the
password input field itself. The type attribute is set to “password”, which
specifies that it should behave as a password input. The id attribute
associates the input with the label, and the name attribute is used to identify
the field when the form is submitted.
The key feature of a password input field is its ability to mask the entered characters to
enhance security. This helps protect sensitive information from being easily visible to
others, especially when entered on shared or public computers. When the form containing
the password input is submitted, the entered value is sent to the server like any other form
input, and it’s the server’s responsibility to handle and store passwords securely.
How Do We Create Password Filed Using HTML Helper in ASP.NET Core
MVC?
To create a Password Input Field, i.e., <input type=”password”> using HTML Helpers in
ASP.NET Core MVC, we must use Password or PasswordFor methods within our Razor
views.
The Password method is used when you manually specify the form field’s name, while
PasswordFor is used with model properties, providing a strongly typed approach. That
means the Password() HTML Helper method is loosely typed, whereas the PasswordFor()
HTML Helper method is strongly typed.
What is the Password HTML Helper Method in ASP.NET Core MVC?
353
The Html.Password() HTML Helper method in ASP.NET Core MVC generates an input
password element with a specified name, value, and HTML attributes. Two overloaded
Password() Helper Method versions are available.
IHtmlContent Password(this IHtmlHelper htmlHelper, string expression)
IHtmlContent Password(this IHtmlHelper htmlHelper, string expression, object value)
Let’s see an example of understanding the Password HTML Helper in ASP.NET Core
MVC. First, create a class file named LoginModel.cs and copy and paste the following
code into it.
namespace HTML_HELPER.Models
{
public class LoginModel
{
public int LoginId { get; set; }
public string? loginName { get; set; }
public string? LoginPassword { get; set; }
}
}
Next, modify the HomeController as follows:
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
Next, modify the Index.cshtml file as follows:
@model HTML_HELPER.Models.LoginModel
@{
Layout = null;
}
354
@Html.Password("LoginPassword")
Run the application and inspect the HTML for the password field text box. It will generate
the following HTML for the Password field.
<input id="LoginPassword" name="LoginPassword" type="password" />
PasswordFor() HTML Helper Method in ASP.NET Core MVC:
The PasswordFor() HTML helper method is the strongly typed extension method. In
ASP.NET Core MVC, Html.PasswordFor() is an HTML Helper method to render an HTML
input element of type “password” for a specified model property. It is typically used within a
form to provide a field for users to enter a password securely.
Syntax: @Html.PasswordFor(expression, htmlAttributes)
Parameters:
expression: A lambda expression that identifies the model property to which
the password input field is bound.
htmlAttributes: An object that contains HTML attributes to be included in the
rendered input element. These attributes can be specified as an anonymous
object.
Let us understand this with an example. Please modify the Index.cshtml file as shown
below.
@model HTML_HELPER.Models.LoginModel
@{
Layout = null;
}
@Html.PasswordFor(m => m.LoginPassword)
It will generate the following HTML Code.
<input id="LoginPassword" name="LoginPassword" type="password">
In the above example, the first parameter of the PasswordFor() helper method is a lambda
expression that specifies the model property to be bound with the password field textbox.
Customizing the Password Input:
You can customize the behavior and appearance of the password input by passing
attributes to the PasswordFor method. For example, modify the Index.cshtml file as
follows:
@model HTML_HELPER.Models.LoginModel
@Html.PasswordFor(m => m.LoginPassword, new { @class = "form-control", placeholder =
"Enter your password" })
Here:
@Html.PasswordFor(m => m.Password): This generates a password input
field bound to the Password property in the model. The value entered by the
user will be assigned to the Password property when the form is submitted.
@class = “form-control”: This is an example of adding a CSS class to the
password input for styling purposes.
355
when you need to include data in the form submission that is not directly related to model
properties or when you want to specify the field’s name and value explicitly.
Syntax: @Html.Hidden(“fieldName”, “value”)
Here, “fieldName” is the name of the hidden field, and “value” is the value assigned to it.
When the form is submitted, the value of this hidden field is sent to the server along with the
other form data.
Example to Understand Hidden HTML Helper in ASP.NET Core MVC
In this demo, we will use the following Student model to understand the Hidden() and
HiddenFor() HTML Helper methods. First, create a class file named Student.cs within the
Models folder and copy and paste the following code into it.
namespace HTML_HELPER.Models
{
public class Student
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Branch { get; set; }
}
}
Next, modify the Home Controller as follows:
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
Student student = new Student() { Id = 1, Name = "Pranaya", Branch = "CSE" };
return View(student);
}
[HttpPost]
public string Index(Student student)
{
return $"Id: {student.Id}, Name: {student.Name}, Branch: {student.Branch}";
}
358
}
}
Modify the Index.cshtml file as follows:
The following example creates a hidden field ID with the Id property of the Student model. It
binds the ID to the hidden field so that it can assign the ID value to it.
@model HTML_HELPER.Models.Student
<div>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
@Html.Hidden("Id", Model.Id)
<label for="Name">Name</label>
@Html.TextBox("Name", Model.Name, new { @class = "form-control", placeholder =
"Enter your Name" })
<label for="Branch">Branch</label>
@Html.TextBox("Branch", Model.Branch, new { @class = "form-control", placeholder =
"Enter your Branch" })
<input type="submit" value="Submit" />
}
</div>
Understanding the code:
Html.BeginForm: This creates the form element with the specified action
and controller names and the form submission method (in this case, POST).
@Html.Hidden: This generates a hidden input field. The first parameter (“Id”)
is the input element’s name, which will be used to identify the data on the
server. The second parameter (Model.Id) is the value you want to send along
with the form.
Now, run the application, and you will see the following output. Please note that it shows the
name and branch but not the student’s ID value.
359
Now, if you inspect the HTML element, you will see that it is generating the following HTML
element for the hidden field.
<input data-val=”true” data-val-required=”The Id field is required.” id=”Id” name=”Id”
type=”hidden” value=”1″ />
Now, when you click on the Submit button, you will see, along with the Name and Brach, it
is also sending the ID value to the server, and you will get the following output.
Using the Hidden HTML Helper, you can ensure that the hidden input fields are generated
correctly with the necessary attributes and values. This approach also promotes cleaner
and more maintainable code.
Note: Please note that hidden fields can still be manipulated by users with some technical
knowledge, so sensitive or critical information should always be validated and processed
securely on the server side.
What is the HiddenFor() HTML Helper Method in ASP.NET Core MVC?
The HiddenFor helper method in ASP.NET Core MVC, on the other hand, is strongly typed
and is used with model properties. It generates a hidden input field for a specific property of
the model bound to the view. This approach ensures type safety and enables direct
mapping between the form field and the model property, reducing the errors due to
mistyped field names.
The HiddenFor() method is strongly typed. which means it is tied to a model property. It
takes a lambda expression as an argument, which specifies the property of the model that
the hidden input element represents. Let us understand this with an example. please modify
the Index.cshtml file as follows:
360
@model HTML_HELPER.Models.Student
<div>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
@Html.HiddenFor(m => m.Id)
<label for="Name">Name</label>
@Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Enter
your Name" })
<label for="Branch">Branch</label>
@Html.TextBoxFor(m => m.Branch, new { @class = "form-control", placeholder = "Enter
your Branch" })
<input type="submit" value="Submit" />
}
</div>
In this example:
Html.BeginForm: This creates the form element as before.
Html.HiddenFor(m => m.Id): This generates a hidden input field based on
the model’s Id property. The lambda expression m => m.ID specifies the
property for which you want to create the hidden field. When the form is
submitted, the ID value will be included in the POST data.
Run the application, and you will get the same output as the previous example.
What are the Differences Between Hidden and HiddenFor Helper
Methods in ASP.NET Core MVC?
In ASP.NET Core MVC, both Hidden and HiddenFor generate hidden input fields.
Understanding the differences between them is important for effective data handling and
manipulation in MVC applications.
Hidden Helper Method in ASP.NET Core MVC
Usage: The @Html.Hidden helper generates a hidden input field that is not
visible to the user but can be used to store and post data back to the server.
It’s useful for storing data that you want to pass back to the server without
displaying it or allowing modification by the user.
Syntax: You can use @Html.Hidden by specifying the name of the data you
want to store and, optionally, the value. For
example, @Html.Hidden(“UserId”, “123”) would generate a hidden input
field for storing a user ID value of “123”.
Flexibility: This method allows for a more flexible naming convention since
you can explicitly specify the input field’s name. This can be useful in
situations where the name of the field doesn’t directly correspond to a
property on your model.
HiddenFor Helper Method in ASP.NET Core MVC
361
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:18 / 03:1110 Sec
}
Creating Images Folder within the wwwroot Folder:
Next, add a folder with the Name Images within the wwwroot Folder. To do so, Right-click
on the wwwroot, select Add Folder, and then rename the folder as Images. Then download
and add the following image to the Images Folder. Rename the image name as
MyPhoto.png.
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
//In Realtime, you will get the data from any data source
Id = 106724,
Designation = "Manager",
Department = "IT",
Photo = "/Images/MyPhoto.png",
};
return View(employee);
}
Modifying the Index.cshtml view file of Home Controller:
Next, open the Index.cshtml view file and then copy and paste the following code into it.
@model HTML_HELPER.Models.Employee
@{
<div>
<h4>Employee Details</h4>
<hr />
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
</div>
Now, Run the application and navigate to the URL Home/Index. It will produce the following
output. Notice that the Photo and AlternateText property values are displayed instead of
rendering the photo.
366
@{
<div>
<h4>Employee Details</h4>
<hr />
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
</div>
Notice that we are using an image HTML tag here. Now, run the application and notice that
the image is displayed as expected, as shown in the image below.
368
We use the code below to render Images in the ASP.NET MVC application. We are building
the image tag by passing the values for the src and alt attributes.
<img src=”@Model.Photo” alt=”@Model.AlternateText”/>
Though the above code is not very complex, moving this logic into its own helper method
still makes sense. We don’t want any complicated logic in our views. Views should be as
simple as possible. Don’t you think it would be very nice if we could render the image using
the Image() HTML helper method as shown below?
@Html.Image(Model.Photo, Model.AlternateText)
But, ASP.NET Core MVC does not provide any built-in Image() HTML helper. So, let’s build
our own custom image HTML helper method.
Custom HTML Helper in ASP.NET Core MVC
Custom HTML helpers are user-defined methods that extend the functionality of built-in
HTML helpers or provide new functionality altogether. They allow developers to encapsulate
common HTML markup patterns or generate complex HTML structures and reuse them
across multiple views.
Custom Image HTML Helper in ASP.NET Core MVC
In ASP.NET Core MVC, we can create a custom HTML Helper method to generate a <img>
tag with additional attributes or behavior. The Custom HTML Helper methods allow us to
encapsulate reusable HTML generation logic in our application. Let us proceed and
understand How We Can Create a Custom Image HTML Helper Method in ASP.NET Core
MVC.
Create a Helper Method:
To create a custom HTML helper in ASP.NET Core MVC, we need to follow the below
steps:
Create a Helper Class: Start by creating a static class to contain your
custom HTML helper methods.
Create Extension Methods: Define extension methods within your helper
class. These methods should extend the IHtmlHelper interface or any derived
interface, allowing you to access HTML generation methods.
Implement Helper Methods: Write the logic for your custom HTML helper
methods within the extension methods. These methods should generate
HTML markup based on the provided parameters.
Register the Helper Class: Register your custom HTML helper class with
the MVC framework during application startup. This step ensures that your
helper methods are available for use throughout your application.
So, create a class file named CustomHTMLHelper.cs (you can give it any name) within
the Models folder (you can create it inside any folder or directory) and then copy and paste
the following code into it.
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Models
{
369
public static TagBuilder Image(this IHtmlHelper helper, string src, string alt, string height,
string width, string cssClass)
imgTag.MergeAttribute("src", src);
if (alt != null)
imgTag.MergeAttribute("alt", alt);
if (Convert.ToInt32(height) > 0)
imgTag.MergeAttribute("height", height);
if (Convert.ToInt32(width) > 0)
imgTag.MergeAttribute("width", width);
if (cssClass != null)
//imgTag.MergeAttribute("class", cssClass);
imgTag.AddCssClass(cssClass);
return imgTag;
}
370
}
Explanation of the above class:
The above class defines a CustomHTMLHelper class in C# that extends the capabilities of
ASP.NET’s IHtmlHelper interface, specifically for generating HTML image tags. The Image
method is an extension method for IHtmlHelper, enabling the dynamic creation of <img>
HTML elements with specified attributes. Here’s a breakdown of its functionality:
Class Definition (public static class CustomHTMLHelper): The class is declared public
and static, meaning it is accessible globally and cannot be instantiated. It’s meant to contain
static methods only, without any instance members.
Extension Method (public static TagBuilder Image(this IHtmlHelper helper, …)): This
method is an extension method, as indicated by the “this” keyword in its first parameter. It
allows the method to be called on any object of type IHtmlHelper, effectively extending that
interface with new functionality. This is useful for adding methods to an interface without
modifying its original definition.
Parameters: The method takes several parameters for constructing an image tag:
src (string): The URL of the image to be displayed.
alt (string): The alternative text for the image, which is displayed when the
image cannot be loaded.
height (string) and width (string): Dimensions for the image. These are set
as attributes only if their converted integer value is greater than 0, which is a
basic validation to ensure that dimensions are positive.
cssClass (string): An optional CSS class to be applied to the image tag for
styling.
TagBuilder Usage: TagBuilder is a utility class for building HTML tags in a structured way.
The code creates a new TagBuilder instance for an <img> tag and sets its attributes based
on the method’s parameters.
Conditional Attributes: The method checks if certain parameters (alt, height, width, and
cssClass) are provided and valid before adding them as attributes to the <img> tag. For
example, it only adds the height and width attributes if their values can be converted to
integers greater than 0. This prevents the generation of invalid HTML.
CSS Class Application: Instead of directly merging the class attribute, the code uses
AddCssClass for the cssClass parameter, which is a more appropriate method for adding
CSS classes as it handles the class attribute’s unique behavior in HTML (e.g., appending to
existing classes).
Return Value: The method returns the constructed TagBuilder object representing the
<img> tag, which can then be rendered to HTML.
Use the Custom HTML Helper:
In your Razor view, you can use the custom HTML Helper to generate the custom image
tag by calling the Image Helper method. So, modify the Index.cshtml file as shown below. In
the below example, the Image Custom HTML Helper method generates a <img> tag with
the specified src, alt, width, height, and CSS class.
@model HTML_HELPER.Models.Employee
@{
371
<div>
<h4>Employee Details</h4>
<hr />
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
</div>
After making the above changes, run the application, and you will get the output as
expected, as shown in the image below.
372
Custom HTML Helpers provide a convenient way to encapsulate complex HTML generation
logic, making your views cleaner and more maintainable. They can be especially useful
when generating custom HTML elements that require specific attributes or behaviors.
Another Way to Use Custom HTML Helper Method:
Now, instead of creating the Image method as an extension method, we can also create this
as a non-extension method and use it inside our views. For example, modify the
CustomHTMLHelper class as follows:
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Models
public static TagBuilder Image(string src, string alt, string height, string width, string
cssClass)
imgTag.MergeAttribute("src", src);
if (alt != null)
imgTag.MergeAttribute("alt", alt);
if (Convert.ToInt32(height) > 0)
imgTag.MergeAttribute("height", height);
if (Convert.ToInt32(width) > 0)
imgTag.MergeAttribute("width", width);
if (cssClass != null)
//imgTag.MergeAttribute("class", cssClass);
imgTag.AddCssClass(cssClass);
return imgTag;
}
Explanation of the above Code:
374
The above code defines a static class called CustomHTMLHelper with a static method
Image that generates an HTML img tag with specified attributes. Here’s a breakdown of the
method:
Parameters:
src: The URL of the image.
alt: The alternate text for the image.
height: The height of the image.
width: The width of the image.
cssClass: The CSS class for the image.
Creating TagBuilder: TagBuilder is a class used to generate HTML tags programmatically.
In this code, a new TagBuilder object for the img tag is created.
Setting Attributes: The mergeAttribute method sets attributes like src, alt, height, and
width of the img tag based on the parameters provided.
The src attribute is always set.
The alt attribute is set only if a non-null value is provided.
The height and width attributes are set only if their corresponding parameters
are greater than 0.
Adding CSS Class: The cssClass parameter is added as a CSS class to the img tag using
the AddCssClass method.
Returning TagBuilder: Finally, the method returns the TagBuilder object representing the
img tag with the specified attributes.
This method provides a convenient way to generate HTML img tags with specified attributes
in a structured manner. It abstracts away the complexity of manually creating and setting
attributes for the img tag, making the code more readable and maintainable. The above
Image method is not an extension method, so we cannot invoke this method using the
@Html property. Instead, we can call this method using the class name, i.e.,
CustomHTMLHelper. So, modify the Index.cshtml file as follows.
@model HTML_HELPER.Models.Employee
@{
<div>
<h4>Employee Details</h4>
<hr />
<p>
</p>
375
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
</div>
Now, run the application, and you should get the same output.
When Should We Use Custom HTML Helper in ASP.NET Core MVC?
Here are some scenarios where using custom HTML Helpers can be advantageous:
Reusable UI Components: If you have UI components that are reused
across multiple views or even multiple projects, creating custom HTML
Helpers can help encapsulate the HTML generation logic, promoting code
reusability and maintainability.
Complex Markup Generation: When you need to generate complex HTML
markup involving multiple elements or conditional logic, custom HTML
Helpers can provide a cleaner and more maintainable way to generate such
markup than embedding the HTML directly within the Razor view.
Consistent Output and Centralized Updates: By centralizing the HTML
generation logic within custom HTML Helpers, you ensure consistency in the
generated output across your application. Additionally, any updates or
modifications to the markup can be made in a centralized location, simplifying
maintenance and reducing the risk of inconsistencies.
Real-Time Examples of Custom HTML Helpers in
ASP.NET Core MVC
376
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:21 / 03:1110 Sec
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Models
{
public static class FormControlHelpers
{
public static IHtmlContent CustomInputWithValidation(this IHtmlHelper htmlHelper,
string modelPropertyName, string labelText)
{
var fullHtml = $@"
<div class='form-group'>
<label for='{modelPropertyName}'>{labelText}</label>
<input type='text' class='form-control' id='{modelPropertyName}'
name='{modelPropertyName}' asp-for='{modelPropertyName}' />
<span asp-validation-for='{modelPropertyName}' class='text-danger'></span>
</div>";
return new HtmlString(fullHtml);
}
}
377
}
Next, modify the Home Controller as follows:
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
Next, modify the Index.cshtml view file as follows. As you can see, we are using the
CustomInputWithValidation HTML Helper method here.
@Html.CustomInputWithValidation("UserName", "User Name")
Example2: Breadcrumb Helper
Displaying navigational breadcrumbs on a site can be streamlined using a custom helper
that takes the current path or a list of paths and then renders the breadcrumb navigation.
Generate breadcrumb navigation based on the provided list of paths. So, create a class file
with the name BreadcrumbHelpers.cs within the Models folder and copy and paste the
following code.
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Models
{
public static class BreadcrumbHelpers
{
public static IHtmlContent Breadcrumbs(this IHtmlHelper htmlHelper, List<(string Url,
string Name)> paths)
{
var stringBuilder = new StringBuilder();
stringBuilder.Append("<nav aria-label='breadcrumb'>");
stringBuilder.Append("<ol class='breadcrumb'>");
378
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Models
{
public static class PaginationHelpers
{
public static HtmlString CreatePagination(this IHtmlHelper htmlHelper, int currentPage, int
totalPages)
{
StringBuilder result = new StringBuilder();
result.Append("<nav><ul class='pagination'>");
for (int i = 1; i <= totalPages; i++)
{
if (i == currentPage)
{
result.Append($"<li class='page-item active'><span class='page-link'>{i}</span></li>");
}
else
{
result.Append($"<li class='page-item'><a class='page-link' href='?page={i}'>{i}</a></li>");
}
}
result.Append("</ul></nav>");
return new HtmlString(result.ToString());
}
}
}
Next, modify the Index.cshtml view as follows. As you can see here, we are using the
CreatePagination HTML Helper method.
@Html.CreatePagination(2, 10)
Example6: Dynamic Menus
Menus that change based on user roles, permissions, or other criteria can be encapsulated
within a custom HTML helper, ensuring consistent rendering across views.
381
Dynamic Menus using Custom HTML Helper Methods in ASP.NET Core MVC. Dynamic
menus often depend on user roles, permissions, or other dynamic criteria. You can
consistently generate these menus across views using a custom HTML helper. Here’s an
example of creating and using a custom HTML helper to generate dynamic menus in
ASP.NET Core MVC.
Step 1: Define Your Menu Model
First, let’s create a class file with the name MenuItem.cs within the Models folder and then
copy and paste the following code into it. This is a simple model for menu items:
namespace HTML_HELPER.Models
{
public class MenuItem
{
public string Text { get; set; }
public string Url { get; set; }
public bool IsActive { get; set; }
public List<MenuItem> SubItems { get; set; } = new List<MenuItem>();
}
}
Step 2: Create a Custom HTML Helper for the Dynamic Menu
Next, create another class file with the name MenuHtmlHelpers.cs within the Models folder
and copy and paste the following code into it. This helper will generate the necessary HTML
based on a list of MenuItem:
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Models
{
public static class MenuHtmlHelpers
{
public static HtmlString DynamicMenu(this IHtmlHelper htmlHelper, List<MenuItem>
menuItems)
{
StringBuilder result = new StringBuilder();
result.Append("<ul class='menu'>");
foreach (var item in menuItems)
{
result.AppendFormat("<li class='{0}'>", item.IsActive ? "active" : "");
382
Imagine you have a profile card that displays a user’s name, profile image, and a short bio.
This card might be reused in different parts of your website: user lists, comments section,
article authors, etc.
Define a Model for the Profile Card
First, let’s create a simple model for the profile card. So, create a class file with the
name ProfileCardModel.cs within the Models folder and copy and paste the following code
into it.
namespace HTML_HELPER.Models
{
public class ProfileCardModel
{
public string Name { get; set; }
public string ProfileImageUrl { get; set; }
public string Bio { get; set; }
}
}
Define Custom HTML Helper:
Create the Custom HTML Helper for the Profile Card. So, create a class file with the
name WidgetHtmlHelpers.cs within the Models folder and copy and paste the following
code into it.
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Models
{
public static class WidgetHtmlHelpers
{
public static HtmlString ProfileCard(this IHtmlHelper htmlHelper, ProfileCardModel
model)
{
StringBuilder result = new StringBuilder();
result.Append("<div class='profile-card'>");
result.AppendFormat("<img src='{0}' alt='{1}' class='profile-img'/>",
model.ProfileImageUrl, model.Name);
result.AppendFormat("<h2>{0}</h2>", model.Name);
result.AppendFormat("<p>{0}</p>", model.Bio);
385
result.Append("</div>");
return new HtmlString(result.ToString());
}
}
}
Using the Custom HTML Helper
Use the Custom HTML Helper in a Razor View. So, modify the Index.cshtml file as follows.
To use the profile card widget, we can invoke the custom helper:
@using HTML_HELPER.Models
@model ProfileCardModel
@Html.ProfileCard(Model)
Modifying Home Controller:
We need to populate the ProfileCardModel from our controller and send it to the view. So,
modify the Home Controller class as follows.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
ProfileCardModel model = new ProfileCardModel
{
Name = "Pranaya Rout",
ProfileImageUrl = "/path/to/image.jpg",
Bio = "Software Developer at ABC Corp."
};
return View(model);
}
}
}
Benefits:
Consistency: By defining the widget’s structure and styling in one place, you
ensure it looks and behaves consistently everywhere it’s used.
386
Easier Maintenance: Changes to the widget (e.g., adding an email field) only
need to be made in one location.
Cleaner Views: Your Razor views are tidier as they can leverage the helper
instead of repeating HTML structures.
Flexibility: By designing your widgets to accept configurations or additional
parameters, you can make them versatile to handle different scenarios or
styles.
Remember, if the widget becomes too complex, or you want to utilize more MVC features,
turning the widget into a View Component might be better than using an HTML helper. View
Components in ASP.NET Core allow you to encapsulate view and logic into a reusable unit,
which is perfect for complex widgets.
Example8: Configurable Data Tables
A table displaying data from various sources with options for sorting, filtering, and specifying
columns. A custom helper can take in this configuration and render the table accordingly.
Creating configurable data tables using custom HTML helper methods can provide a flexible
and reusable way to display tabular data across your application. Here’s a basic example to
illustrate the process.
Define a Model for the Data Table Configuration
Firstly, define the configuration for the data table, specifying the columns you want to
display and any other properties you may need. So, create a class file with the
name DataTableConfig.cs within the Models folder and copy and paste the following code
into it.
namespace HTML_HELPER.Models
{
public class DataTableConfig
{
public List<string> Columns { get; set; }
public string TableClass { get; set; } = "table"; // default CSS class
}
}
Create another class file named MyCustomDataType.cs and copy and paste the following
code into it. This is the class that is going to hold the model data.
namespace HTML_HELPER.Models
{
public class MyCustomDataType
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
387
}
Create the Custom HTML Helper for the Data Table
Next, design your custom HTML helper. So, create a class file
named DataTableHtmlHelpers.cs within the Models folder and copy and paste the
following code into it.
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text;
namespace HTML_HELPER.Models
{
public static class DataTableHtmlHelpers
{
public static HtmlString DataTable<T>(this IHtmlHelper htmlHelper, IEnumerable<T>
data, DataTableConfig config)
{
StringBuilder result = new StringBuilder();
// Table start
result.AppendFormat("<table class='{0}'>", config.TableClass);
// Header
result.Append("<thead><tr>");
foreach (var column in config.Columns)
{
result.AppendFormat("<th>{0}</th>", column);
}
result.Append("</tr></thead>");
// Body
result.Append("<tbody>");
foreach (var item in data)
{
result.Append("<tr>");
foreach (var column in config.Columns)
{
var value = item.GetType().GetProperty(column)?.GetValue(item, null);
result.AppendFormat("<td>{0}</td>", value);
388
}
result.Append("</tr>");
}
result.Append("</tbody>");
// Table end
result.Append("</table>");
return new HtmlString(result.ToString());
}
}
}
Use the Custom HTML Helper in a Razor View
Now, you can use the data table widget in a Razor view. So, modify the Index.cshtml file as
follows.
@using HTML_HELPER.Models
@model IEnumerable<MyCustomDataType>
@{
var config = new DataTableConfig
{
Columns = new List<string> { "Name", "Age", "Address" }
};
}
@Html.DataTable(Model, config)
Modifying Home Controller:
From your controller, you need to populate a list of MyCustomDataType and send it to the
view. So, modify the Home Controller as follows.
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
List<MyCustomDataType> data = new List<MyCustomDataType>
389
{
new MyCustomDataType { Name = "Pranaya", Age = 35, Address = "123 ABC St." },
new MyCustomDataType { Name = "Kumar", Age = 34, Address = "456 PQR St." },
new MyCustomDataType { Name = "Rout", Age = 33, Address = "789 XYZ St." }
};
return View(data);
}
}
}
Notes:
Flexibility: This example provides a basic structure. You can extend the
DataTableConfig class with more configuration options (e.g., specifying which
columns are sortable, adding custom classes for specific columns, etc.).
Complex Columns: This example assumes each column is tied to a direct
property on the data type. If you have more complex columns, adjustments
would be needed.
Consider using View Components or integrating a dedicated front-end library for large,
complex, or highly interactive tables.
By implementing custom HTML helpers for these use cases, developers can ensure
consistency, reduce errors, and simplify the process of making global changes to the
application’s views.
{
public class UserProfile
{
public int? Id { get; set; }
[Required(ErrorMessage ="Name Field is Required")]
public string Name { get; set; }
[Required(ErrorMessage = "Biography Field is Required")]
public string Biography { get; set; }
public string Gender { get; set; }
public List<string> Skills { get; set; } = new List<string>();
public bool NewsLetter { get; set; }
public string Preference { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
}
}
Create a Controller
Create a controller with actions to display and process the form. The controller will have two
actions: one for displaying the form (HTTP GET) and another for processing the form input
(HTTP POST). So, create an Empty MVC Controller named UserProfileController under
the Controllers folder and copy and paste the following code.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:07 / 03:1110 Sec
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace HTML_HELPER.Controllers
{
public class UserProfileController : Controller
{
[HttpGet]
public IActionResult Index()
{
// You can populate this with data from a database in a real app.
391
}
<h2>User Profile Form</h2>
@using (Html.BeginForm("Index", "UserProfile", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.LabelFor(model => model.Name)
@Html.TextBoxFor(model => model.Name, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.LabelFor(model => model.Biography)
@Html.TextAreaFor(model => model.Biography, new { @class = "form-control", rows =
3 })
@Html.ValidationMessageFor(model => model.Biography, "", new { @class = "text-
danger" })
</div>
</div>
<div class="form-group">
<div class="form-check form-check-inline">
@Html.RadioButtonFor(model => model.Gender, "Male", new { @class = "form-check-
input" })
@Html.LabelFor(model => model.Gender, "Male", new { @class = "form-check-label" })
</div>
<div class="form-check form-check-inline">
@Html.RadioButtonFor(model => model.Gender, "Female", new { @class = "form-check-
input" })
@Html.LabelFor(model => model.Gender, "Female", new { @class = "form-check-label" })
</div>
</div>
393
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.LabelFor(model => model.Skills)
@Html.ListBoxFor(model => model.Skills, (SelectList)ViewBag.SkillsList, new { @class =
"form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.NewsLetter)
<div class="form-check">
@Html.CheckBoxFor(model => model.NewsLetter, new { @class = "form-check-input" })
@Html.LabelFor(model => model.NewsLetter, "", new { @class = "form-check-label" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.LabelFor(model => model.Preference)
@Html.DropDownListFor(model => model.Preference, (SelectList)ViewBag.PreferenceList,
"Please Select", new { @class = "form-control" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.LabelFor(model => model.Password)
@Html.PasswordFor(model => model.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-
danger" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
@Html.HiddenFor(model => model.Id)
</div>
394
</div>
<button class="btn btn-primary" type="submit">Submit</button>
}
@if (TempData["Success"] != null)
{
<div>@TempData["Success"]</div>
}
Using HTML Helpers
BeginForm: Starts the form using the specified action method.
TextBoxFor: Renders an input of type text for a specified model property.
TextAreaFor: Renders a textarea for a specified model property.
DropDownListFor: This function renders a select list (dropdown) for a
specified model property using a provided list of values.
RadioButtonFor: Renders a radio button for a specified model property.
CheckBoxFor: Renders a checkbox for a specified model property.
ListBoxFor: Renders a list box for a specified model property.
HiddenFor: Renders a hidden input for a specified model property, useful for
storing IDs that are not changed by the user.
PasswordFor: Renders an input of type password for a specified model
property.
How It Works
GET Request: When a user navigates to the /UserProfile/Index, the Index
action method with [HttpGet] is invoked, which displays the form to the user.
POST Request: Upon form submission, the browser sends a POST request
to the server, hitting the Index action method with [HttpPost]. The method
attempts to save the data and, upon success, redirects to the same Index
action method, which displays the message from the TempData. If an error
occurs, then it will display the error message.
Key Points of Bootstrap:
Form and Grid: The form uses the Bootstrap grid system (form-row and col-
md-6 mb-3) to organize the form fields. This ensures that the layout is
responsive and adapts to different screen sizes.
Form Controls: Form elements are styled with Bootstrap’s form-control class
for a unified and attractive appearance.
Buttons: The submit button uses the btn btn-primary class for styling
consistent with the Bootstrap theme.
Running the Application
When you run the application and navigate to /UserProfile/index, you’ll see the UserProfile
form, as shown below.
395
Submitting the form with valid data should display a success message, indicating that the
POST action in the UserProfileController processed the form submission.
In ASP.NET Core MVC, generating links is a common task that can be achieved in several
ways. These techniques enable you to create URLs that can lead to different parts of your
application, such as controller actions, static files, or external websites. Here are some of
the most common methods for generating links in ASP.NET Core MVC:
Html.ActionLink
Html.RouteLink
Action Tag Helper
Url.Action
Url.RouteUrl
Html.ActionLink
Html.ActionLink is an HTML helper method used in ASP.NET Core MVC views to generate
an anchor (<a>) element that links to a specific action method on a controller.
Syntax: Html.ActionLink(“Link Text”, “ActionName”, “ControllerName”, new { id =
“Parameter” }, new { @class = “cssClass” })
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:17 / 03:1110 Sec
“Link Text”: The text to display for the link.
“ActionName”: The name of the action method in the controller.
“ControllerName”: The name of the controller (without the “Controller”
suffix).
new { id = “Parameter” }: Route values for the action method parameters.
This is optional.
new { @class = “cssClass” }: HTML attributes for the anchor tag. This is
optional.
When to use: Generates a hyperlink to an action method by using the action name and
controller name. Use Html.ActionLink when you need to generate a straightforward link to
an action method from within a Razor view. It’s useful when the link text and the action are
straightforward to define inline.
Html.RouteLink
The Html.RouteLink method is one of the ways to generate links to different routes within
your application. This method is especially useful when you want to generate a link based
on route name and parameters rather than controller and action names directly.
Syntax: @Html.RouteLink(“Link Text”, “RouteName”, new { id = 1 }, new { @class =
“css-class” })
Here,
“Link Text” is the display text for the link.
“RouteName” is the name of the route.
The third parameter is for route values. This is optional.
The fourth parameter is for HTML attributes. This is optional.
When to use: Generates a hyperlink based on a route name and route values. Use
Html.RouteLink when you have complex routing requirements that cannot be easily
addressed by specifying action and controller names alone. It is particularly useful when
you want to generate a link that adheres to a specific routing configuration defined in your
Program.cs.
397
}
ProductsController
Let’s assume we have a Products controller with two actions: List (to display a list of
products) and Details (to display details of a specific product). We want to create links in our
views that direct users to these actions. So, create an empty MVC Controller
named ProductsController and then copy and paste the following code:
using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
};
return View(_products);
return View(product);
}
Creating a Route:
Next, add the following code to the Program.cs class file. Here, we are adding a new route
with the name ProductDetails. We will use this route name inside a view to generate the
link.
app.MapControllerRoute(
name: "ProductDetails",
pattern: "Products/Details/{id}",
This view displays a list of product names and uses different mechanisms to generate links
to the details of each product:
@model IEnumerable<HTML_HELPER.Models.Product>
@{
ViewData["Title"] = "List";
<h2>Product List</h2>
<table class="table">
<thead>
<tr>
<th>
Name
</th>
<th>
ActionLink
</th>
<th>
RouteLink
</th>
<th>
Tag Helper
</th>
<th>
Action
</th>
402
<th>
RouteUrl
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
@item.Name
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
403
</td>
<td>
</td>
</tr>
</tbody>
</table>
Details View (Details.cshtml)
This view displays the details of a single product. The DisplayNameFor helper methods
display the model property’s name, and the DisplayFor method displays the associated
value of a model property.
@model HTML_HELPER.Models.Product
@{
ViewData["Title"] = "Details";
<div>
<h4>Product Details</h4>
<hr />
<dl class="row">
</dt>
404
</dd>
</dt>
</dd>
</dt>
</dd>
</dt>
</dd>
</dt>
405
</dd>
</dt>
</dd>
</dl>
</div>
<div>
</div>
Now, run the application and navigate to the Products/List URL, and you should see the
following page:
Now, if you click any of the links, then it should open the Details Page as shown in the
below image:
406
Conquering the clouds on a journey to Ta Xua with the team - Road Trip Vietnam Team
- Nếm TV00:03 / 02:5410 Sec
<a asp-controller=”Home” asp-action=”Index”>Link</a>: Generates a
link with a URL that’s generated by routing based on the specified controller
and action.
<img src=”~/images/pic.jpg” asp-append-version=”true” />: Generates a
<img> tag with a cache-busting query string to ensure the latest version of the
image is fetched.
<form asp-controller=”Account” asp-action=”Login” method=”post”>…
</form>: Generates a form element with the appropriate action attribute for
the specified controller and action.
<input asp-for=”Username” />: Generates an input field with attributes
based on the model property specified by asp-for.
Custom Tag Helpers:
Custom Tag Helpers allow us to encapsulate complex UI logic and generate HTML output
based on our application’s requirements. They are defined by extending the TagHelper
class and overriding its methods.
To create a custom Tag Helper, we need to define a class that derives from
the TagHelper base class and override the Process/ProcessAsync method to generate
the desired HTML output. You can then use your custom Tag Helper in your Razor views by
referencing it with the appropriate HTML-like syntax.
Note: In this article, I will give an overview of Built-in Tag Helpers, and in our upcoming
articles, I will discuss How to Create Custom Tag Helpers.
Built-in Tag Helpers Type in ASP.NET Core MVC:
In ASP.NET Core MVC, several built-in HTML Tag Helpers cover common HTML elements
and scenarios. These tag helpers simplify generating HTML markup while still allowing you
to incorporate server-side logic. Here are some of the types of HTML Tag Helpers available:
409
</form>
Image Tag Helper (<img>):
This tag helper generates image elements with the appropriate src attribute. You can use it
to include images in your views. Example:
<img src="~/images/pic.jpg" alt="Picture">
Input Tag Helpers (Various Input Elements):
These tag helpers generate various types of input elements such as text boxes,
checkboxes, radio buttons, etc. Examples include:
<input asp-for="Name" />
</cache>
Localization Tag Helpers:
These help render content based on the current culture and provide localized strings.
Example:
<localized asp-culture="en-US">Hello!</localized>
Environment Tag Helper:
This tag helper conditionally renders content based on the hosting environment. It can be
useful for including different content for development and production environments.
Partial Tag Helper:
This tag helper renders a partial view within another view. It’s useful for breaking down
complex views into smaller components.
410
}
Modifying Home Controller:
Modify the HomeController as shown below. Here, we have created two action methods. To
simplify things and keep the focus on Tag helpers, we have hard-coded the required
student data using the action method. 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
returns that student information to the view.
using TagHelpersDemo.Models;
using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.Controllers
public HomeController()
//In Real-Time, you will get the data from the database
412
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" }
};
//Pass the Student List to the View to make the view as a Strongly Typed View
return View(listStudents);
//Pass the Student model to the View to make the view as a Strongly Typed View
return View(studentDetails);
413
}
Creating Details View:
Create a view named Details.cshtml within the Views=>Home folder, then copy and paste
the following code.
@model TagHelpersDemo.Models.Student
@{
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="col-sm-8">
<div class="card">
<h1>@Model?.Name</h1>
</div>
<h4>Studnet ID : @Model?.StudentId</h4>
<h4>Branch : @Model?.Branch</h4>
<h4>Section : @Model?.Section</h4>
<h4>Gender : @Model?.Gender</h4>
</div>
</div>
</div>
</div>
</div>
Modifying Index View:
Now, in the index view, we have to provide the View button as a link. When we click the
View button, we need to display the Student Details. For example, we need to generate the
following hyperlink. The number 101 is the ID of the student whose details we want to view.
/home/details/101
There are many different methods for generating a link in the ASP.NET Core MVC
Application. Let’s discuss all the possible options, and then we will discuss why we should
use Tag Helper over others.
Method 1: Using HTML Element:
In this case, we need to use the anchor tag, and in the href attribute, we need to specify the
path of the details action method along with the student id like <a
href=”/home/details/@student.StudentId”>View</a>. So, modify the Index action
method of the Home Controller as follows.
@model List<TagHelpersDemo.Models.Student>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>View</th>
</tr>
415
</thead>
<tbody>
<tr>
<td>@student.StudentId</td>
<td>@student.Name</td>
</tr>
</tbody>
</table>
</div>
With the above changes in place, run the application and navigate to the Root URL
or Home/Index URL. You should see the following page on the web browser.
416
Once you click on the View button, it will execute the Details action method of the Home
Controller by passing the Student ID value 101, and hence, you will see the following
Details view of the Home Controller showing the Student details.
Using HTML Helper methods, we can also generate the link. In this case, we need to use
the ActionLink Helper method to generate the link like @Html.ActionLink(“View”,
“Details”, “Home”, new {id = student.StudentId}).
Here, the parameter View is nothing but the link text; the second parameter Details is the
Action method name; the third parameter Home is the controller’s name, and the fourth
parameter is object routeValues, which specifies the id parameter value. So, modify
the Index.cshtml view of the Home Controller as follows to use the HTML Helper Method to
generate the link.
@model List<TagHelpersDemo.Models.Student>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>View</th>
</tr>
</thead>
<tbody>
<tr>
<td>@student.StudentId</td>
<td>@student.Name</td>
418
</tr>
</tbody>
</table>
</div>
With the above changes in place, run the application and see if everything is working as
expected.
Method 3: Using Tag Helpers:
To use Tag Helpers, first, we need to import the @addTagHelper directive in
the _ViewImport.cshtml file. We also add the model namespace using
the @using directive. So, modify the _ViewImport.cshtml file as shown below, which you
can find within the Views folder.
@using TagHelpersDemo
@using TagHelpersDemo.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
With these changes in place, you can now access the types defined with the above-using
namespace throughout the application without re-specifying the namespace and all the tag
helpers you can access from all the views. Next, modify the Index view of the Home
Controller as shown below. Here, we are using Tag Helpers.
@model List<TagHelpersDemo.Models.Student>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="table-responsive">
<table class="table">
<thead>
<tr>
419
<th>ID</th>
<th>Name</th>
<th>View</th>
</tr>
</thead>
<tbody>
<tr>
<td>@student.StudentId</td>
<td>@student.Name</td>
<td>
<a asp-controller="Home"
asp-action="Details"
asp-route-id="@student.StudentId">View</a>
</td>
</tr>
</tbody>
</table>
</div>
Now, run the application, and it should work as expected.
Understanding Anchor Tag Helper in ASP.NET Core MVC:
The Anchor Tag Helper in ASP.NET Core creates the standard HTML anchor (<a … ></a>)
tag by adding attributes such as:
420
As you can see in the above image, manually generating the links is much easier than using
HTML Helpers or Tag Helpers. So why should we use HTML helpers or Tag Helpers
instead of manually generating these links in ASP.NET Core?
Why should we use Tag Helpers over manually generating these links in
ASP.NET Core?
In ASP.NET Core MVC, Tag Helpers generate links based on the application routing
templates. That means if we change routing templates in the future, the links generated by
tag helpers will automatically reflect those changes. So, the generated links work as
expected without any trouble.
On the other hand, if we have hard-coded the URL paths manually, we need to change the
code wherever we have hard-coded the path in our application when the application routing
templates change. Let’s understand this with an example. The following is the Main method
of the Program class of our application.
namespace TagHelpersDemo
{
421
builder.Services.AddControllersWithViews();
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();
}
422
}
As you can see in the above code, currently, we have the route template pattern
as {controller=Home}/{action=Index}/{id?}.
Generating Link Manually: We can generate the link manually using the following code by
hard-coding the URL paths as /Home/Details.
<a href=”/Home/Details/@student.StudentId”>View</a>
Generating Link using Tag Helper: In the following code, we generate the link using
anchor tag helper.
<asp-controller=”Home” asp-action=”Details” asp-route-
id=”@student.StudentId”>View</a>
As you can see with Tag Helper, we have not hardcoded the URL paths. Here, we only
specify the controller and action name, route parameters, and their values. When the tag
helpers are executed on the server, they automatically look at the route templates and
generate the correct URLs.
Here, both the techniques generate the same URL path, i.e. (/Home/Details/101), and it
also works with the current route template, i.e. ({controller=Home}/{action=Index}/{id?})
Now, let us change the routing template as shown below. Notice here the route template
pattern. We have added the string literal “dotnet”.
So, with the above changes in place, manually generating the link will not work if you run
the application, whereas the link generating with Tag Helpers will work as expected.
You can also disable the browser cache. Once you disable the browser cache, the images
will not be cached; instead, they will be downloaded from the server each time you visit the
page. To disable the browser cache in Google Chrome, follow the steps below.
Press the F12 key to launch the Browser Developer Tools. Then click on
the “Network” tab, and finally, check the “Disable Cache” checkbox as shown in the
below image.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:09 / 03:1110 Sec
improve page loading performance by indicating the image dimensions to the browser
before the image is fully loaded.
<img src="~/images/Image1.jpg" alt="My Image" width="200" height="150" />
Additional Attributes:
The Image Tag Helper supports other attributes you might want to use with the <img> tag,
such as class, style, alt, and more.
<img src="~/images/Image1.jpg" alt="My Image" class="img-thumbnail" style="border:
1px solid #ccc;" />
Using Model Binding:
You can also use the Image Tag Helper with model binding. If your view model has an
image property, you can bind it directly to the src attribute. Assuming your view model has a
property named ImageUrl:
<img asp-src="@Model.ImageUrl" alt="Image">
In this case, the asp-src attribute binds to your model’s ImageUrl property, generating the
appropriate src attribute.
Understanding ASP.NET Core Image Tag Helper With an Example:
First, create a folder with the name images within the wwwroot folder of your application.
Once you create the images folder, add images with the
names Image1.jpg and Image2.jpg. For better understanding, add two different images, as
shown in the below image.
425
Once you add the above two images, your wwwroot folder should look as shown below.
Next, modify the Index View as shown below. Here, we have only the img tag, which loads
the image Image1.jpg from the images folder. Along with the src attribute, where we set the
path of the image, we have also used the asp-append-version attribute and set its value to
true.
@{
ViewBag.Title = "Index";
Layout = null;
}
<img src="~/images/Image1.jpg" asp-append-version="true" />
With the above changes in place, run the application, and you should get the output as
expected, as shown in the image below. Next, right-click on the page and then click on view
the page source, as shown in the image below.
Once you view the page source code, you will find the following code for the image tag.
428
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:17 / 03:1110 Sec
430
As software developers, we generally use this development environment for our day-to-day
development work. In this environment, we generally use non-minified JavaScript and
CSS files for easy debugging. Another use of this environment is that we want to show
the developer exception page if there is an unhandled exception so that we can understand
the root cause of the exception and then take necessary action to fix the issue.
Who Works Here: Software developers primarily work in this environment.
It’s their playground for writing code, developing features, and performing
initial unit tests.
Responsibilities: Developers are responsible for implementing new features,
fixing bugs, and ensuring their code meets initial quality standards before it’s
moved to the next environment.
Testing Environment
The Testing Environment is Dedicated to testing and quality assurance. Here, the software
is tested for bugs, errors, and issues that weren’t caught during initial development. This
Environment Mirrors the production environment as closely as possible to ensure that
testing conditions resemble the final usage scenario. This environment may also be referred
to as the QA (Quality Assurance) environment.
Who Works Here: QA engineers and testers are the primary users of this
environment. Their expertise is in systematically finding and reporting bugs,
as well as verifying bug fixes.
Responsibilities: QA professionals run various tests, including functional
tests, regression tests, and sometimes automated tests, to ensure the
software meets all requirements and is free of defects.
Staging Environment:
A “Staging Environment” is a phase in the software development lifecycle that comes after
the development/testing environment and before the production environment. The staging
environment serves as an intermediate testing ground where the application is tested in an
environment that closely resembles the production environment. Its primary purpose is to
identify and address any issues, bugs, or discrepancies before the application is deployed
to actual users in the production environment.
The staging environment is very much similar to the production environment. Nowadays,
many organizations use this staging environment to identify any deployment-related issues.
Again, if you are developing a B2B (business-to-business) application, you may use
services provided by other service providers. So, many organizations set up their staging
environment to check the service providers as well for complete end-to-end testing.
We usually do not perform the debugging and troubleshooting in the staging environment,
so we need to use the minified JavaScript and CSS files to perform better. Again, if there is
an exception, we need to show a friendly error page instead of showing the developer
exception page. The friendly error page will not contain any details about the exceptions.
Instead, it shows a generic error message like the one below.
“Something went wrong. Our IT team is working to solve this as soon as possible. If
you need further details, please Email, Chat, or Call our support team using the
contact details below.”
Who Works Here: A mix of QA engineers, developers, and sometimes
product managers or clients. This environment is a pre-production mirror
used for final checks.
431
Now, if you want to load the non-minified bootstrap CSS files from your server when the
application environment is in Development, then you need to set the environment tag helper
as shown below.
Suppose you want to load the minified bootstrap CSS files from the CDN (Content Delivery
Network) when the application environment is Staging or Production. In that case, you need
to set the environment tag helper, as shown below. As you can see, we have specified
multiple environments separated by a comma.
To get the bootstrap CDN link, please visit the following URL.
https://getbootstrap.com/
Once you visit the above URL, you will see the following page. From here, you need to copy
either CSS, JS, or both as per your application’s requirements. In our example, we only
need CSS, so copy the Bootstrap CDN path of CSS only.
435
Using the Include attribute of the Environment Tag Helper, we can set a single hosting
environment name or a comma-separated list of hosting environment names like Staging
and Production. Along with the include attribute, we can also use the exclude attribute.
The Exclude attribute is basically used to render the content of the environment tag when
the hosting environment does not match the environment specified in the exclude attribute.
The following example loads the minified CSS file from the CDN when the application
environment is not in Development.
resource. This is useful when you have complete control over the fallback content and are
less concerned about its integrity being compromised (e.g., hosted on your own server).
Modifying the _Layout.cshtml file:
Please modify the _Layout.cshtml file as shown below. Here, we are loading the
bootstrap.css files based on the application environment. We also specify the fallback path
if the environment is other than Development and the CDN is down. If the Environment is
Development, it will load the non-minified bootstrap.css file from our server. If the
Environment is other than Development, first, it will try to load the minified bootstrap.min.css
file from CDN, and if the CDN is down, it will load the minified bootstrap.min.css file from
our server.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<environment include="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
<link rel="stylesheet"
integrity="sha384-
9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"
crossorigin="anonymous"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
asp-fallback-href="~/lib/twitter-bootstrap/css/bootstrap.min.css"
asp-fallback-test-class="sr-only"
asp-fallback-test-property="position"
asp-fallback-test-value="absolute"
asp-suppress-fallback-integrity="true" />
</environment>
</head>
<body>
<div class="container">
@RenderBody()
</div>
</body>
438
</html>
Modifying Home Controller:
Next, modify the Home Controller as shown below. Here, we are simply creating one action
method.
using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
}
}
Modifying Index.cshtml View:
Next, modify the Index.cshtml view as follows.
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index View</h1>
Run the application and view the page source code; you should see the following.
439
As you can see in the above image, the boostrap.css file is loaded from our server, i.e.,
from wwwroot folder of our application. This makes sense because we have set the
application environment as Development in the launchsettings.json file. Let us change the
environment to Staging and see whether or not it loads the minified version of the Bootstrap
file from CDN.
Modify the Environment as Staging:
Open the launchsettings.json file and modify
the ASPNETCORE_ENVIRONMENT variable value to staging, as shown below. We are
making changes for both IIS Express and Kestrel Web Server.
With the above changes in place, run the application and view the page source code. It
should now show the bootsrap.css file being downloaded from the CDN, as shown below.
440
asp-fallback-test-value="absolute"
asp-suppress-fallback-integrity="true" />
</environment>
</head>
<body>
<div class="container">
@RenderBody()
</div>
</body>
</html>
With the above changes in place, run the application. To confirm whether it is loading
Bootstrap from the local server, open the Developer Browser Tool by pressing the F12 key,
navigate to the Network, and refresh the page. You should see there are two requests
for bootstrap.min.css. This is because the first request is made for CDN, and it gets a 200
success response from CDN, but while matching the integrity value, it failed, and hence it
again makes a call to the local server to download the bootstrap.min.css file, which is
shown in the below image.
The Environment Tag Helper in ASP.NET Core MVC is a built-in Tag Helper that allows you
to conditionally render content in your Razor views based on the current hosting
environment. This Tag Helper is useful when displaying different content or applying
different behaviors depending on whether your application runs in a development, staging,
or production environment.
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:23 / 03:1110 Sec
But when we open our website on a small screen device like a mobile, we want to show the
navigation menus like the one below. Here, you can see the menus List, Create, About, and
Contact are not visible; instead, the hamburger menu (three horizontal lines) is visible, and
once we click on the three horizontal lines, it will display all the menus.
443
Let us Proceed and see How we can Implement the above using the ASP.NET Core MVC
Application.
Creating a New ASP.NET Core MVC Application:
First, we create a new ASP.NET Core Application using the Model-View-Controller Project
Template named FirstCoreMVCApplication. Once we create the project, we must add the
required Bootstrap and jQuery files.
Adding Bootstrap and jQuery files:
The most important point you need to remember is that Bootstrap depends on jQuery. So,
we need to download both Bootstrap and jQuery into our application. Here, we will use a
tool called Library Manager (LibMan) to download the required Bootstrap and jQuery files.
So, please follow the steps below to install Bootstrap for 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 is “cdnjs” 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, it tries installing the latest Bootstrap version. Here, we are installing the
latest version of Bootstrap, i.e. ([email protected]) at this point. While
you are reading this article, the latest version might be updated.
4. There are two radio buttons to select whether to include “All library files” or
“Choose Specific files“. 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
444
Once it is successfully installed, you will find two things: the libman.json
file and the required bootstrap files, as shown in the image below.
445
In the same way, you can install jQuery using Libary Manager. The other option to install
the jQuery file is to open the libman.json file and then copy and paste the following code
into it.
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
"library": "[email protected]",
"destination": "wwwroot/lib/twitter-bootstrap/"
},
446
"provider": "cdnjs",
"library": "[email protected]",
"destination": "wwwroot/lib/jquery/"
}
As you can see in the above code, here we are adding [email protected]. It will automatically
install the required jQuery files inside the lib folder.
Adding images Folder inside the wwwroot folder:
Add a folder called images with the wwwroot folder and then paste two different images
with the names Logo.png and Student.png, as shown in the image below.
width: 80px;
}
With the above changes in place, your wwwroot folder should look as shown below.
447
@using FirstCoreMVCApplication.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Modifying _Layout.cshtml file:
Use the Bootstrap Navbar component to create your navigation menu. Bootstrap’s Navbar
automatically becomes responsive and will toggle between a horizontal menu and a
hamburger menu on smaller screens.
Please modify the _Layout.cshtml file, which is present inside the Views => Shared folder,
as shown below. In the head section, we refer to the files MyCustomStyleSheet.css,
bootstrap.css, query.js, and bootstrap.js. The navbar-toggler button is a responsive
component that will appear on smaller screen sizes. When clicked, it toggles the visibility of
the navigation menu items.
<!DOCTYPE html>
448
<html>
<head>
<title>@ViewBag.Title</title>
<script src="~/lib/jquery/jquery.js"></script>
<script src="~/lib/twitter-bootstrap/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<div class="container-fluid">
</a>
<span class="navbar-toggler-icon"></span>
</button>
<li class="nav-item">
</li>
<li class="nav-item">
</li>
<li>
</li>
<li>
</li>
</ul>
</div>
</div>
</nav>
<div>
@RenderBody()
</div>
</div>
</body>
</html>
Explanation of the above Code:
Navigation Menu
<nav style="margin-top:15px" class="navbar navbar-expand-sm bg-dark navbar-dark">:
450
</a>
When clicked, a link that acts as the website’s brand logo navigates to the Home
Controller’s Index action. The ASP.NET Core MVC uses the asp-controller and asp-action
tags for routing.
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-
target=".navbar-collapse" aria-controls="navbarSupportedContent"
<span class="navbar-toggler-icon"></span>
</button>
This is a button for toggling the navigation bar on small screens. It uses Bootstrap’s
collapse plugin to control the visibility of the navigation links.
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
This section contains the navigation links. Due to the d-sm-inline-flex class, it collapses on
small screens and becomes horizontal on larger screens.
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
</li>
</ul>
The list of navigation links. Each tag uses asp-controller and asp-action attributes for routing
to different application parts (e.g., List, Create, About, Contact).
Main Content Area
<div>
@RenderBody()
</div>
451
@RenderBody() is a placeholder where the content of individual views that use this layout
will be rendered. Each page’s specific content will appear here.
Note: The jQuery reference must be loaded before loading the Bootstrap JavaScript file for
the navbar toggle button to work on a small-screen device. If you change the order,
the navbar toggle button does not work as expected.
Creating Models:
First, we need to create two enums to store the Gender and Branch of a student. So, create
two classes within the Models folder named Gender.cs and Branch.cs.
Branch.cs
Open the Branch.cs class file and copy and paste the following code. As you can see, we
have created the Branch enum with four named constants, i.e., None, CSE, ETC, and
Mech.
namespace FirstCoreMVCApplication.Models
None,
CSE,
ETC,
Mech
}
Gender.cs
Next, open the Gender.cs class file and copy and paste the following code. As you can
see, we have created the Gender enum with two named constants, i.e., Male and Female.
namespace FirstCoreMVCApplication.Models
Male,
Female
452
}
Student Model:
We want to display the student information on the web page. So, create a class file
named Student.cs within the Models folder and copy and paste the following code.
using System.Collections.Generic;
namespace FirstCoreMVCApplication.Models
}
Modifying Home Controller:
Next, modify the Home Controller as shown below. As you can see in the code below, we
have added two action methods. The Index action method will return all the students, while
the Details action takes the student ID and returns that student’s information.
using FirstCoreMVCApplication.Models;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
namespace FirstCoreMVCApplication.Controllers
453
public HomeController()
};
return View(listStudents);
return View(studentDetails);
}
Modifying Index.cshtml file:
Please modify the Index view, which is present inside the Home folder, as shown below.
Notice how the buttons (View, Edit, and Delete) are attached to each other. Use the
Bootstrap margin classes (m-1, m-2, etc.) to include the margin between these buttons. In
the class name, “m” stands for margin, and the numbers 1, 2, 3, etc., are the size of the
space you want between the buttons. In this view, List<Student> is the model, and using a
for each loop, we are accessing all the students. Further, if you notice, we have used Tag
Helper to generate the link for the View button.
@model List<Student>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="row">
<div class="col-sm-3">
455
<div class="card-header">
<h3>@student.Name</h3>
</div>
<div class="card-body">
</div>
</div>
</div>
</div>
</div>
Creating Detail.cshtml file:
Please create a view named Details.cshtml within the Views/Home folder and copy and
paste the following code into it. In this view, the Student will be the model, and we can
access the student model properties using the @Model object.
@model Student
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
456
<div class="col-sm-8">
<div class="card">
<div class="card-header">
<h1>@Model?.Name</h1>
</div>
<h4>Studnet ID : @Model?.StudentId</h4>
<h4>Email : @Model?.Email</h4>
<h4>Branch : @Model?.Branch</h4>
<h4>Gender : @Model?.Gender</h4>
<h4>Address : @Model?.Address</h4>
</div>
</div>
</div>
</div>
</div>
Program.cs Class:
Please modify the Program class code as follows. Actually, we are not making any changes
in the Main method of the Program class as we have created the Project using Model-View-
457
Controller, which by default includes all the required MVC services and middleware in the
request processing pipeline.
namespace FirstCoreMVCApplication
builder.Services.AddControllersWithViews();
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(
458
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
}
Now, run your application and resize the browser window, or use a mobile device to see the
responsive navigation menu in action. On smaller screens, the menu items should collapse
into a hamburger menu (three horizontal lines). When you click the hamburger menu, it will
show the menu items in a dropdown fashion.
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:34 / 03:1110 Sec
asp-action: Specifies the action method to be called on form submission.
asp-controller: Specifies the controller that contains the action method.
asp-route: Used for additional route values.
asp-antiforgery: Automatically includes anti-forgery tokens if set to true
(default is true).
To create a Form in ASP.NET Core MVC View, we need to use the <form> tag helper. The
syntax for using the Form Tag Helper is shown below. The <form> tag helper binds to the
<form> HTML element. We can specify which action and controller the form should submit
to using the asp-action and asp-controller attributes.
<form asp-controller="Home" asp-action="Create" method="post">
</form>
As you can see in the above code, we are using the asp-controller and asp-action attributes
within the Form Tag Helper. These two tag attributes specify the controller and the action
method to submit the form data. The method attribute specifies whether it is a Get or Post
460
Request. When the form is submitted, we want to issue a post request, so we set the
method type to post. If you want to submit the data to an action method of HTTP Get type,
you need to specify the method type as Get.
Note: If you didn’t specify the controller and action name using the asp-controller and asp-
action tag helpers, then by default, when the form is submitted, it will invoke the same
action method of the controller that rendered the form.
Input Tag Helper in ASP.NET Core MVC:
<input>: Generates input elements and automatically binds them to model properties
asp-for: Specifies the model property to which the input is bound.
asp-isrequired: Adds the required attribute if the model indicates the
required field.
The input tag helpers bind to the <input> HTML element. These are versatile and generate
different input types based on your model attributes. This helps to automate the generation
of id, name, and value attributes based on model property conventions, facilitates validation,
and provides enhanced Razor syntax highlighting and IntelliSense support. The type of
input generated is inferred from the model property’s type. For instance:
string maps to type=”text”
bool maps to type=”checkbox”
DateTime or DateTime? maps to type=”datetime-local”
Here, we want a form to create a new Student. So, the model for our view is Student class,
and we can specify the model using the following directive.
@model Student
We want to display a text box in our form to capture the student’s name. We also want that
text box to bind with the Name property of the Student model class. This can be done easily
using the asp-for Tag helper, as shown below.
<input asp-for="Name" class="form-control">
As you can see here, we set the value for the asp-for tag helper to the Name property of
the Student model class. You will also get IntelliSense support while setting the value
property. Later, if you change the property name from Name to StudnetName on the
Student class and do not change the value assigned to the tag helper, you will get a
compiler error.
The above input tag helper generates an input element with id and name attributes. Both
the ID and name are set to a value such as Name, as shown below.
<input type="text" id="Name" name="Name" value="" class="form-control">
Label Tag Helper in ASP.NET Core MVC:
<label>: Automatically generates labels associated with model properties. It helps in
generating correct for attributes linking the label to the respective input.
asp-for: Specifies which model property this label is for.
Using the asp-for attribute, the <label> tag helper can generate a label for an associated
input element. The Label Tag Helper in ASP.NET Core generates a label. The “asp-for”
attribute links the label with its corresponding input element. For example,
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control">
The above code generates the following HTML.
461
<label for="Name">Name</label>
<input type="text" id="Name" name="Name" value="" class="form-control">
Here, the label is linked with the input element. This is because the label for the attribute
and the input element id attribute have the same value (i.e., Name). That means the
corresponding input element will receive the focus when we click on the label.
TextArea Tag Helper in ASP.NET Core MVC:
The <textarea> tag helper functions similarly to the input tag helper and binds to the
<textarea> HTML element. But here, it specifically targets the Textarea element instead of
the input element. The textarea tag helper adds the asp-for tag helper attribute to a text
area element. For example, let’s say our Student model has a property to store the address,
then for address property, we can use textarea tag helper as shown below.
<textarea asp-for="Address" class="form-control"></textarea>
The text area tag helper will generate Name and Id properties based on the Property Name
specified in the asp-for attribute. If you want to display the textarea with a specified number
of rows and cols, you need to use the following attributes.
<textarea asp-for="Address" rows="4" cols="30" class="form-control"></textarea>
Checkbox tag helper in ASP.NET Core MVC:
In ASP.NET Core MVC, you can use the input tag helper to create checkboxes. Suppose
we have a model class named Student with a property IsRegular of boolean type indicating
whether the student is a regular student or not. To create a checkbox for the IsRegular
property, we would use the input tag helper as follows:
<label>
<input asp-for="IsRegular" type="checkbox" /> Is Regular Student
</label>
The asp-for attribute binds the checkbox to the IsRegular property. When the form is
submitted, the value of the checkbox (either true or false) will be bound to the IsRegular
property of the model. By default, if the value of IsRegular Property in the model is true, the
checkbox will be rendered as checked. Otherwise, it will be unchecked.
Select Tag Helper in ASP.NET Core MVC:
<select>: Generates drop-down lists bound to model properties.
asp-for: Specifies the model property to bind the select to.
asp-items: Specifies the options for the dropdown list.
The Select Tag helper in ASP.NET Core generates a select tag with associated option
elements. Let us assume the following Branches Property hold the list of all branches.
public List<SelectListItem> Branches{ get; set; }
In our example, we want a dropdown list to display the list of Branches. We also want a
label that should be linked with the select element. The following code does the same.
<label for="Branch">Branch</label>
<select asp-for="Branch" asp-items="Model.Branches"></select>
462
The options for the branch select element can be hard-coded like in the example below, or
they can also come from an enum or a database table. In our example, we will use an enum
for the select options.
<label for="Branch">Branch</label>
<select id="Branch" name="Branch">
<option value="0">None</option>
<option value="1">CSE</option>
<option value="2">ETC</option>
<option value="3">Mech</option>
</select>
Radio Button Tag Helper in ASP.NET Core MVC:
The radio button control is designed to support selecting only one of a mutually exclusive
set of predefined options. In ASP.NET Core MVC, the radio button tag helper can be used
to generate <input type=”radio”> elements that bind to model properties. This is
particularly helpful for scenarios where you want to provide multiple options but allow only
one selection.
Let’s consider an example to illustrate the use of the radio button tag helper. Assume we
have a model property Gender with possible values “Male,” “Female,” and “Other.” Let us
assume we have a property called Gender in our model to hold the Gender value. In our
Razor view, we can use the tag helper to bind radio buttons to the Gender property as
follows.
<input asp-for="Gender" type="radio" value="Male" id="male" />
<label for="male">Male</label>
<input asp-for="Gender" type="radio" value="Female" id="female" />
<label for="female">Female</label>
<input asp-for="Gender" type="radio" value="Other" id="other" />
<label for="other">Other</label>
Here, the asp-for attribute is set to the model property (Gender in this case). Each radio
button has a different value attribute, representing each possible value for the Gender
property. The id attribute binds the <label> elements to the respective radio buttons. When
the form is submitted, the Gender property of the model will be populated with the value of
the selected radio button, thanks to the model binding.
Validation Tag Helpers in ASP.NET Core MVC:
<span>: Displays validation messages.
asp-validation-for: Specifies the model property for which the validation
message is displayed.
asp-validation-summary: Specifies the validation summary display mode
(All, ModelOnly, or None).
Syntax: <span asp-validation-for=”Email” class=”text-danger”></span>
Generating Hidden Inputs
To generate a hidden input field:
463
Mech
}
}
Student.cs
Create a class file with the name Student.cs and copy and paste the following code into it.
This will be a class that will hold the student data, and this will be our model.
namespace FirstCoreMVCApplication.Models
{
public class Student
{
public int StudentId { get; set; }
public string? Name { get; set; }
public string? Email { get; set; }
public string? Password { get; set; }
public Branch? Branch { get; set; }
public Gender? Gender { get; set; }
public bool IsRegular { get; set; }
public string? Address { get; set; }
public DateTime DateOfBorth { get; set; }
}
}
Modifying Home Controller:
Next, modify the Home Controller as follows. Here, we are adding the Create action
method.
using FirstCoreMVCApplication.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace FirstCoreMVCApplication.Controllers
{
public class HomeController : Controller
{
//Create a Variable to Hold List of Students
//This is going to be our data source
private List<Student> listStudents = new List<Student>();
465
public HomeController()
{
//Within the Constructor we are Initializing listStudents variable
//In Real-Time, we will get the data from the database
listStudents = new List<Student>()
{
new Student() { StudentId = 101, Name = "James", Branch = Branch.CSE, Gender =
Gender.Male, Address = "A1-2018", Email = "[email protected]" },
new Student() { StudentId = 102, Name = "Priyanka", Branch = Branch.ETC, Gender =
Gender.Female, Address = "A1-2019", Email = "[email protected]" },
new Student() { StudentId = 103, Name = "David", Branch = Branch.CSE, Gender =
Gender.Male, Address = "A1-2020", Email = "[email protected]" },
new Student() { StudentId = 104, Name = "Pranaya", Branch = Branch.Mech, Gender =
Gender.Male, Address = "A1-2021", Email = "[email protected]" }
};
}
public ViewResult Index()
{
//returning all the students
return View(listStudents);
}
public ViewResult Details(int Id)
{
//returning the student based on the Student Id
var studentDetails = listStudents.FirstOrDefault(std => std.StudentId == Id);
return View(studentDetails);
}
[HttpGet]
public ViewResult Create()
{
ViewBag.AllGenders = Enum.GetValues(typeof(Gender)).Cast<Gender>().ToList();
ViewBag.AllBranches = new List<SelectListItem>()
{
466
<div class="col-sm-10">
<input asp-for="Password" class="form-control" placeholder="Enter Your Password">
</div>
</div>
<div style="margin-top:7px" class="form-group row">
<label asp-for="Branch" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<select asp-for="Branch" class="custom-select mr-sm-2"
asp-items="Html.GetEnumSelectList<Branch>()"></select>
@*<select asp-for="Branch" asp-items="ViewBag.AllBranches"></select>*@
</div>
</div>
<div style="margin-top:7px" class="form-group row">
<label asp-for="IsRegular" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input type="checkbox" class="custom-control-input" asp-for="IsRegular">
</div>
</div>
<div style="margin-top:7px" class="form-group row">
<label asp-for="DateOfBorth" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="DateOfBorth" class="form-control">
</div>
</div>
<div style="margin-top:7px" class="form-group row">
<label asp-for="Gender" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
@foreach (var gender in ViewBag.AllGenders)
{
<label class="radio-inline">
<input type="radio" asp-for="Gender" value="@gender" id="Gender@(gender)"
/>@gender<br />
</label>
468
}
</div>
</div>
<div style="margin-top:7px" class="form-group row">
<label asp-for="Address" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<textarea asp-for="Address" class="form-control" placeholder="Enter Your
Address"></textarea>
</div>
</div>
<div style="margin-top:10px" class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Create</button>
</div>
</div>
</form>
</div>
Modifying Layout View:
If you are coming directly to this article without reading our previous article, then please
modify the _Layout.cshtml view as follows:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="~/css/MyCustomStyleSheet.css" rel="stylesheet" />
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<script src="~/lib/jquery/jquery.js"></script>
<script src="~/lib/twitter-bootstrap/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<nav style="margin-top:15px" class="navbar navbar-expand-sm bg-dark navbar-dark">
469
bind form elements to model properties, manage validation, and handle form submissions,
making the Razor views cleaner and more maintainable.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
<ul>
471
<li><a href="/Home">Home</a></li>
<li><a href="/About">About</a></li>
<li><a href="/Contact">Contact</a></li>
</ul>
</nav>
Using Partial Tag Helper in ASP.NET Core MVC:
Now, in any of your primary views or layouts where you wish to include this navigation
menu, you can use the Partial Tag Helper as follows:
<partial name="_NavigationMenu" />
Additional Attributes of Partial Tag Hellper:
model: The model you want to pass to the partial view. It’s optional. If your partial view
expects a model, you can pass it using the model attribute:
<partial name="_PartialViewName" model="YourModelInstance" />
view-data: Any additional view data you want to pass to the partial view.
<partial name="_PartialViewName" view-data="ViewDataDictionaryInstance" />
fallback-name: The name of the partial view that will be used if the specified partial view in
the name isn’t found.
<partial name="_PartialViewName" fallback-name="_FallbackPartialViewName" />
fallback-view-data: The view data passed to the fallback partial view if it’s used.
<partial name="_PartialViewName" fallback-view-
data="FallbackViewDataDictionaryInstance" />
render-mode: Defines whether the partial view should be rendered synchronously (Server)
or asynchronously (ServerPrerendered). By default, it is ServerPrerendered, i.e., rendering
asynchronously.
<partial name="_PartialViewName" render-mode="ServerPrerendered" />
Here, render-mode can be one of the following:
Server (default): Renders the partial view synchronously.
ServerPrerendered: Renders the partial view asynchronously.
By following these steps, you can efficiently use the Partial Tag Helper in your ASP.NET
Core MVC project to render partial views, making your views more modular and your code
reusable.
Partial Tag Helper Real-Time Example in ASP.NET Core MVC:
Let’s understand the usage of the built-in Partial Tag Helper in an ASP.NET Core MVC
Application with an example. Imagine you are building a web application that displays blog
posts. Each blog post has a comment section. To modularize the views, you have decided
472
to put the comments section into a partial view. Let’s understand how we can implement
this using the Partial Tag Helper.
Creating Models:
We are going to use the following BlogPost and Comment models:
Comment.cs
Create a class file with the name Comment.cs within the Models folder, and then copy and
paste the following code into it.
namespace TagHelpersDemo.Models
}
BlogPost.cs
Create a class file named BlogPost.cs within the Models folder, then copy and paste the
following code into it.
namespace TagHelpersDemo.Models
}
Creating Partial View:
Create a partial view named _Comments.cshtml in the Views/Shared folder and then
copy and paste the following code into it.
@model List<Comment>
<div>
<div class="comment">
</div>
</div>
Modifying Controller:
Next, modify the HomeController as follows. As you can see, the Index Action method
returns the BlogPost view:
using Microsoft.AspNetCore.Mvc;
using TagHelpersDemo.Models;
namespace TagHelpersDemo.Controllers
//In Real-Time, you will get the data from the database
Id = id,
};
return View(post);
}
Creating Main View (BlogPost.cshtm):
Create a new View with the name BlogPost.cshtml within the Views => Home folder, and
copy and paste the following code. In the main view where we want to display the blog post,
we can use the Partial Tag Helper to display the comments.
@model BlogPost
@{
475
ViewData["Title"] = "BlogPost";
Layout = null;
<p>@Model.Content</p>
NextStayThe Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:35 / 03:1110 Sec
public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput
output);
public virtual void Process(TagHelperContext context, TagHelperOutput output);
Based on our requirements, we need to override either one or both. The Process (or
ProcessAsync) method is responsible for generating the HTML that the browser will render.
It receives context object, i.e., TagHelperContext instance and TagHelperOutput instance,
which we can use to read and change the content of our tag helper. If this is not clear at this
moment, don’t worry; we will try to understand this with examples.
Example to Understand Tag Helper in ASP.NET Core MVC:
First, create a folder named TagHelpers inside the project root directory. This is where we
will be creating our custom Tag Helpers.
In the next step, create a class file named MyCustomTagHelper inside the TagHelpers
folder. It is recommended that the proper naming convention be followed. The point you
need to remember is that the name of the Tag Helper should end with the suffix TagHelper.
Our newly created MyCustomTagHelper class should be derived from the TagHelper class,
which contains two virtual methods: Process and ProcessAsync. These methods are
responsible for rendering the output of our custom Tag Helper, and we would use them
according to our project’s requirements:
So, once you create the MyCustomTagHelper.cs class file, please copy and paste the
following code.
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace TagHelpersDemo.TagHelpers
477
{
public class MyCustomTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
}
}
}
Parameters
TagHelperContext context: This parameter provides information about the environment in
which the Tag Helper is executed. It contains details about the attributes applied to the Tag
Helper element in the Razor view and other information about the surrounding context.
TagHelperOutput output: This parameter allows you to manipulate the HTML that will be
output by the Tag Helper. It gives you control over what gets rendered to the view from your
Tag Helper. TagHelperOutput has several important properties and methods:
TagName: Gets or sets the HTML element’s tag name. Changing this value
can change the resulting tag or even remove it if set to null.
Attributes: A collection to manage the attributes of the tag. You can add,
remove, or modify attributes.
Content: Manages the inner HTML of the element. You can set content,
append content, or replace existing content.
Process Method Functionality
Within the Process method, we can use the output parameter to change the HTML output
based on the logic we write. This could involve changing the tag itself, modifying attributes,
or altering the inner content. The method does not return a value; instead, it directly
modifies the output instance to produce the desired output.
Now, let us set some of the properties using TagHelperOutput. Modify
the MyCustomTagHelper.cs class as follows. The following MyCustomTagHelper class is
designed to output HTML content that displays details about an employee.
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Text;
namespace TagHelpersDemo.TagHelpers
{
public class MyCustomTagHelper : TagHelper
{
// PascalCase gets translated into Camel-case.
// Can be passed via <my-custom employee-id="..." />.
public int EmployeeId { get; set; }
// Can be passed via <my-custom employee-name="..." />.
478
@{
ViewBag.Title = "Index";
Layout = null;
}
<my-custom employee-id="1001" employee-name="Pranaya Rout"
designation="Manager"></my-custom>
With the above changes, run the application, and you will get the following output.
If you inspect the generated HTML, you will see the following code generated.
<EmployeeSectionTagHelper>
<span>Employee Id:</span> <strong>1001</strong><br/>
<span>Employee Name:</span> <strong>Pranaya Rout</strong><br/>
<span>Employee Designation:</span> <strong>Manager</strong><br/>
</EmployeeSectionTagHelper>
Passing Model Data to a Custom Tag Helper
We can also use the model binding techniques to pass the model data to a custom Tag
Helper. In the following example, we will create three properties that take the given model
expressions: EmployeeId, EmployeeName, and Designation. So, create a class file
named Employee.cs within the Models folder and copy and paste the following code into it.
namespace TagHelpersDemo.Models
{
public class Employee
{
public int EmployeeId { get; set; }
public string? EmployeeName { get; set; }
public string? Designation { get; set; }
}
481
}
Next, modify the Index action method of the Home Controller as follows:
using Microsoft.AspNetCore.Mvc;
using TagHelpersDemo.Models;
namespace TagHelpersDemo.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
Employee employee = new Employee()
{
EmployeeId = 1,
EmployeeName = "Pranaya",
Designation= "Manager"
};
return View(employee);
}
}
}
Next, modify the Index.cshtml view as follows:
@model Employee
@{
ViewBag.Title = "Index";
Layout = null;
}
<my-custom employee-id="@Model.EmployeeId" employee-
name="@Model.EmployeeName" designation="@Model.Designation"></my-custom>
We don’t need to make any changes in our MyCustomTagHelper class. With these changes
in place, run the application, and you will get the output as expected, as shown in the below
image.
482
Now, run the application, and you should get the output as expected.
Another Way to Pass Model Data to Custom Tag Helper:
First, modify the MyCustomTagHelper class as follows:
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Text;
namespace TagHelpersDemo.TagHelpers
{
[HtmlTargetElement("employee-details")]
public class MyCustomTagHelper : TagHelper
{
[HtmlAttributeName("for-id")]
public int EmployeeId { get; set; }
[HtmlAttributeName("for-name")]
public string? EmployeeName { get; set; }
[HtmlAttributeName("for-designation")]
public string? Designation { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//TagName: The HTML element's tag name.
//A whitespace or null value results in no start or end tag being rendered.
output.TagName = "EmployeeSectionTagHelper"; // Set the HTML element name
//TagMode: Syntax of the element in the generated HTML.
//StartTagAndEndTag: Include both start and end tags.
output.TagMode = TagMode.StartTagAndEndTag;
//Create a String Builder Object to Hold the Employee Informations
var sb = new StringBuilder();
sb.AppendFormat($"<span>Employee Id:</span> <strong>{EmployeeId}</strong><br/>");
483
sb.AppendFormat($"<span>Employee Name:</span>
<strong>{EmployeeName}</strong><br/>");
sb.AppendFormat($"<span>Employee Designation:</span>
<strong>{Designation}</strong><br/>");
//Convert the StringBuilder Object to String Type and
//then set that string as the content either using SetContent and SetHtmlContent method
//Content: Get or set the HTML element's main content.
//SetHtmlContent: Sets the content.
//output.Content.SetHtmlContent(sb.ToString());
//output.Content.SetContent(sb.ToString());
output.Content.SetHtmlContent(sb.ToString());
}
}
}
Next, modify the Index.cshtml view as follows:
@model Employee
@{
ViewBag.Title = "Index";
Layout = null;
}
<employee-details for-id="@Model.EmployeeId" for-name="EmployeeName" for-
designation="Designation"></employee-details>
<br/><br/>
<employee-details for-id="@Model.EmployeeId" for-name="@Model.EmployeeName"
for-designation="@Model.Designation"></employee-details>
Custom Tag Helpers Real-Time Examples in ASP.NET Core MVC
As we already discussed, Custom Tag Helpers in ASP.NET Core MVC is a powerful way to
enhance the HTML rendering process by adding custom behavior or transformations to
specific tags or attributes. They enable server-side code to generate or manipulate HTML
elements in Razor views. Let’s look at a couple of real-time examples of Custom Tag
Helpers in ASP.NET Core MVC Applications:
Email Obfuscate Tag Helper
Imagine you want to protect email addresses on your site from being used by spambots.
Obfuscate meaning is to make something less clear and harder to understand, especially
intentionally. One approach is to obfuscate the email address in the HTML. We can create a
484
Custom Tag Helper and Obfuscate the email address for this. So, create a class file
named EmailTagHelper.cs and copy and paste the following code into it.
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Net;
namespace TagHelpersDemo.Models
{
//We need to access this Custom tag using using the tag called email
[HtmlTargetElement("email")]
public class EmailTagHelper : TagHelper
{
private const string EmailDomain = "dotnettutorials.net";
// Can be passed via <email mail-to="..." />.
// PascalCase gets translated into kebab-case.
public string MailTo { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// Change the tag name to <a>
// Replaces <email> with <a> tag
output.TagName = "a";
var address = MailTo + "@" + EmailDomain;
//Set the href attribute of the anchot tag as the email address
output.Attributes.SetAttribute("href", "mailto:" + address);
var obfuscatedEmail = "Email Us";
output.Content.SetContent(obfuscatedEmail);
}
}
}
Next, modify the Index.cshtml view as follows:
@{
ViewBag.Title = "Index";
Layout = null;
}
<email mail-to="info"></email>
Now, run the application and see the following in the browser.
485
If you inspect the generated HTML, you will see that the following HTML code is generated
behind the scenes.
<a href="mailto:[email protected]">Email Us</a>
External Link Tag Helper
If you want to ensure that external links open in a new tab and are marked with a specific
CSS class, you can use Custom Tag Helper. So, create a class file
named ExternalLinkTagHelper.cs and then copy and paste the following code into it.
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace TagHelpersDemo.Models
{
[HtmlTargetElement("a", Attributes = "external-link")]
public class ExternalLinkTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("target", "_blank");
//output.Attributes.SetAttribute("rel", "noopener noreferrer");
output.Attributes.Add("class", "external-link");
}
}
}
Next, modify the Index.cshtml file as follows.
@{
ViewBag.Title = "Index";
Layout = null;
}
<a href="https://dotnettutorials.net" external-link> Visit Dot Net Tutorials</a>
486
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:07 / 03:1110 Sec
https://dotnettutorials.net/lesson/view-components-in-asp-net-core-mvc/
As we already discussed in our View Component article, a view component consists of 2
files in ASP.NET Core. They are as follows:
Server-Side File (.cs file).
Client Side File (.cshtml file)
The Server-Side (.cs) File can be created anywhere in the project. However, we generally
create a new folder (with the name Components, ViewComponents) at the root level of the
project, and we need to place all the view components inside this new folder.
The Client-Side (.cshtml) file of a view component must be placed at a specific location.
They are as follows:
Location1: 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
location: /Views/{Controller Name}/Components/{View Component
Name}/{View Name}
Location2: If we want to call the view component from the other cshtml file,
then we need to add the view component client-side file at the
location: /Views/Shared/Components/{View Component Name}/{View
Name}
Location3: If we are using a view component in Razor pages, then we need
to add the view component client-side file at the
location: /Pages/Shared/Components/{View Component Name}/{View
Name}
Note: The name for each view component file should be Default.cshtml.
Create a View Component:
First, create a folder named ViewComponents within the project root directory. Suppose
the name of the view component server-side file is MyComponent; then, we must add the
487
suffix ViewComponent to it. Hence, the final name of the view component server-side file
will be MyComponentViewComponent.
The View Component class must and should be derived from the ViewComponent class.
This ViewComponent class provides methods for the logic and data preparation needed to
render the view component. So, create a class file with the
name MyComponentViewComponent.cs within the ViewComponents folder and copy
and paste the following code into it.
using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.ViewComponents
{
public class MyComponentViewComponent : ViewComponent
{
public IViewComponentResult Invoke(string param)
{
// Logic or Data Retrieval
// Returns the Default view with the passed param
return View("Default", param);
}
}
}
View Component Client-Side File in ASP.NET Core MVC:
We are using ASP.NET Core MVC and want to invoke the view component from a view file.
Hence, we need to place the client-side file at the
location: Views/Shared/Components/MyComponent
Once you create the Default.cshtml view file within the above-specified folder, your Views
folder should look like the one shown below.
Now, open Default.cshtml view file and then copy and paste the following code into it.
@model string
<div>
This is the content of the View Component with parameter: @Model
</div>
488
<vc:my-component param="Hello"></vc:my-component>
When rendered, this will invoke the Custom Tah helper, which will invoke the View
Component, which will render its corresponding view.
By creating this tag helper for the view component, we can use a custom tag to embed the
view component in your Razor views, leading to more readable and maintainable code.
The Interesting Things About Pha Din Pass, Dien Bien That Just A Few People
Know00:10 / 03:1110 Sec
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Use the Cache Tag Helper:
Then, you can use the <cache> tag helper to denote the portion of the view you want to
cache as follows.
<cache>
<!-- Your content to cache goes here. -->
</cache>
Attributes of the Cache Tag Helper:
expires-after: Sets a sliding expiration time, where the cache entry expires if
not accessed for the specified duration.
expires-on: Sets an absolute expiration date and time for the cache entry.
expires-sliding: Another way to specify sliding expiration. Sets a sliding
expiration time. The cache entry will expire if not accessed within this time
491
period.
The first request to the page that contains the Tag Helper displays the current date.
Additional requests show the cached value until the cache expires (default 20 minutes) or
until the cached date is evicted from the cache.
Enabled Attribute:
The enabled Attribute of the Cache tag helper in ASP.NET Core MVC determines if the
content enclosed by the Cache Tag Helper is cached. The default is true. If set to false, the
rendered output is not cached.
<cache enabled="true">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Expires-on Attribute:
The expiration-on attribute of Cache Tag Helper in ASP.NET Core MVC sets an absolute
expiration date for the cached item. The following example caches the contents of the
Cache Tag Helper until 05:15 AM on January 15, 2026:
<cache expires-on="@new DateTime(2026,1,15,05,15,0)">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Expires-after:
The expiration-after attribute of the cache tag helper in ASP.NET Core MVC sets the time
from the first request time to cache the contents. The following example caches a portion of
the view for 10 minutes.
<cache expires-after="@TimeSpan.FromMinutes(10)">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Every time you refresh the page within 10 minutes, you will notice the timestamp won’t
change because the content is cached.
Expires-sliding Attribute
It is similar to expires-after, but the expiry will be renewed after every access. It is a
TimeSpan type.
<cache expires-sliding="@TimeSpan.FromMinutes(10)">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-header Attribute:
493
The vary-by-header Attribute of the Cache Tag Helper in ASP.NET Core MVC accepts a
comma-delimited list of header values that trigger a cache refresh when they change. The
following example monitors the header value User-Agent and caches the content for every
different User-Agent presented to the web server.
<cache vary-by-header="User-Agent">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-query Attribute:
The vary-by-query Attribute of Cache Tag Helper in ASP.NET Core MVC accepts a comma-
delimited list of Keys in a query string (Query) that triggers a cache refresh when the value
of any listed key changes. The following example monitors the values of Name and ID. The
example caches the content for every different Name and ID presented to the web server:
<cache vary-by-query="Name,Id">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-cookie Attribute:
The vary-by-cookie accepts a comma-delimited list of cookie names that trigger a cache
refresh when the cookie values change. The following example monitors the cookie
associated with ASP.NET Core Identity. When a user is authenticated, a change in the
Identity cookie triggers a cache refresh:
<cache vary-by-cookie=".AspNetCore.Identity.Application">
<p>This Content is Generated </p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-user Attribute:
The vary-by-user specifies whether or not the cache resets when the signed-in user (or
Context Principal) changes. The current user is also known as the Request Context
Principal and can be viewed in a Razor view by referencing @User.Identity.Name. The
following example monitors the current logged-in user to trigger a cache refresh:
<cache vary-by-user="true">
Welcome, @User.Identity.Name! Your personalized content is here.
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
This attribute maintains the cache’s contents through a sign-in and sign-out cycle. When the
value is set to true, an authentication cycle invalidates the cache for the authenticated user.
The cache is invalidated because a new unique cookie value is generated when a user is
494
authenticated. The cache is maintained for the anonymous state when no cookie is present,
or the cookie has expired. If the user is not authenticated, the cache is maintained.
Vary-by Attribute:
The vary-by attribute of Cache Tag Helper in ASP.NET Core MVC allows the customization
of the data cached. When the object referenced by the attribute’s string value changes, the
content of the Cache Tag Helper is updated.
The following example assumes the controller method rendering the view sums the integer
value of the two route parameters, myParam1 and myParam2, and returns the sum as the
single model property. When this sum changes, the content of the Cache Tag Helper is
rendered and cached again. So, first, modify the Home Controller as follows:
using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.Controllers
{
public class HomeController : Controller
{
public IActionResult Index(string myParam1, string myParam2)
{
int num1;
int num2;
int.TryParse(myParam1, out num1);
int.TryParse(myParam2, out num2);
return View("Index", num1 + num2);
}
}
}
Next, modify the Index.cshtml view as follows:
@model int
<cache vary-by="@Model">
<p>Result : @Model</p>
Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary by Query String
Cache content based on a specific query string value. Different cached content will be
stored for different category query string values.
<cache vary-by="@Context.Request.Query["category"]">
Showing products for category: @Context.Request.Query["category"]
<br/>
495