Unit-2 Net Core Framework
Unit-2 Net Core Framework
Prepared By:
Dr. Suchita Patel
Assistant Professor
M.Sc. (IT) Department, ISTAR
Once you click on the Create a new project tab, the Create a new project window will
open. In this window, select the ASP.NET Core Empty project template and click the
Next button, as shown in the image below.
Once you click on the Next button, it will open the Configure Your New Project window.
Here, provide the necessary information to create a new project. First, give an
appropriate name for your project (FirstCoreMVCWebApplication), set the location
where you want to create this project, and the solution name for the ASP.NET Core Web
application. And finally, click on the Create button, as shown in the image below.
Once you click on the Next button, it will open the Additional Information window.
Here, you need to select .NET Framework. You also need to check the Configure for
HTTPS and do not use top-level statements check boxes. Finally, click the Create
button, as shown in the image below.
Once you click the Create button, a new ASP.NET Core Web Application will be created
in Visual Studio 2022 using .NET 8. The project will have the following file and folder
structure.
By default, the Empty template does not include the MVC setup. Let’s see how to set up
MVC in the ASP.NET Core application.
How to Setup MVC in ASP.NET Core Application:
Note: In ASP.NET Core, along with the AddMVC() method, we also have the
AddControllersWithViews() method.
Now open the HomeController.cs class file and copy and paste the following code. To
make a class as a controller in ASP.NET Core MVC, that class must be inherited from
the Controller base class. So, you can see in the below code that our controller, i.e.,
HomeController, is inherited from the Controller base class. This Controller base class
belongs to Microsoft.AspNetCore.Mvc namespace.
With the above changes in place, now run the application, and you will get the following
output.
We are not getting the output from the HomeController’s Index action method. The
above output comes from the MapGet method, which you can find within the Program
class’s Main method.
We need to tell the ASP.NET Core MVC Framework to use the Index action method of
our Home Controller as the default route. To do so, we must add the Required MVC
Middleware Component (UseRouting and MapDefaultControllerRoute) to the
application request processing pipeline.
The UseRouting middleware adds the routing capabilities to the request processing
pipeline. Its primary objective is to match incoming HTTP requests to the corresponding
route endpoint definitions.
It matches the incoming request URL to the routes that are defined in the application.
This is essential for directing requests to the appropriate controllers and actions.
Syntax: app.UseRouting();
MapDefaultControllerRoute Middleware in ASP.NET Core:
The MapDefaultControllerRoute method is a shorthand method to configure the default
route for MVC controllers. Its primary objective is to set up a conventional routing
pattern that maps URLs to controllers and actions using a predefined template.
So, modify the Main Method of the Program class as shown below. The UseRouting()
and MapDefaultControllerRoute() Middleware Components add the MVC
Middleware to the Request Processing Pipeline.
Run the application, and you should get the expected output, as shown in the image
below.
How do we specify a custom controller and action method?
The MapControllerRoute method is used to define a custom route for MVC controllers in
an ASP.NET Core application. Its primary objective is to map incoming HTTP requests to
specific controllers and actions based on a defined URL pattern.
It allows us to specify custom URL patterns that map to controllers and actions,
providing flexibility in how URLs are structured.
It also defines a custom URL pattern that specifies how URLs should be parsed and
matched to controller actions.
We can also define multiple routes using MapControllerRoute to handle different URL
patterns and route them to different controllers and actions.
So, modify the Main method of the Program class to use the MapControllerRoute
Middleware component instead of the MapDefaultControllerRoute() middleware as
follows.
Now, run the application, and you should get the output as expected.
So, in short, to set up MVC in the ASP.NET Core Web Application, we first need to add
the required MVC Services to the dependency injection container and then configure the
required MVC Middleware Components to the Request Processing Pipeline.
If it finds a matching URL pattern for the incoming request, it forwards the
request to the appropriate controller and action method. If there is no
match for the incoming HTTP request URL Pattern, it returns a 404 HTTP
status code to the client. For a better understanding, please have a look at
the following diagram.
What are the Different Types of Routing Supported by ASP.NET Core
MVC?
We can configure routes in the ASP.NET Core MVC Web Application in two
ways. They are as follows:
1. Convention-Based Routing
2. Attribute-Based Routing.
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.
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.
Once you click the Create button, the following Additional Information
window will open: Please select Framework .NET 8.0 (Long-term
support) and 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.
Once you click the Create button, the project will be created using the
Model-View-Controller template with the following folder and file
structure.
Modifying the Home Controller:
Once you have created the Project, next modify the Home Controller as
follows:
In the ASP.NET Core MVC Web Application, the controller action method
handles incoming HTTP Requests, i.e., URLs. For example, if we issue a
request to the /Home/Index URL, then the Index action method of the
Home Controller class will handle the request, as shown in the image
below.
Similarly, if we issue a request to the /Home/Details/2 URL, then the Details
action method of the Home Controller class will handle the request, as
shown in the image below. Here, the parameter value 2 is automatically
mapped to the id parameter of the Details action method.
Now, the question that should come to your mind is, we have not explicitly
defined any routing rules for our 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 is registered into the
Request Processing Pipeline.
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.
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.
We need to access the rest of the controllers and actions 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.
Note: 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. It’s a good practice to give each route a unique name. This
helps when generating URLs based on route names. You can specify
controller, action, and parameter default values. This is useful for defining
fallbacks for missing parts of the route.
Attribute Routing:
Let us first modify the Student Controller as shown below. Here, we have
applied the Route Attribute at the Action methods level.
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
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.
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
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?}”)].
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.
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
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
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.
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.
With the above code in place, we can access the Index() action method
using the following 3 URLs.
/
/Home
/Home/Index
Along the same line, we can access the Details(int? id) action method
using the following 2 URLs.
/Home/Details
/Home/Details/2
If you look at our code, you will see that we are using Route Attributes at
the action method level to define routes. Further, you will notice that all the
routes in the HomeController start with the same prefix, i.e., Home. That
means Home is the common prefix for all the routes in the Home
Controller.
Here, instead of writing the common prefix Home at each action method,
we can specify the Home for the Home Controller (for all its action
methods) using the [Route] attribute at the controller level.
So, modify the Home Controller class as follows. Here, you can see we have
applied [Route(“Home”)] at the controller level, and we have removed
that Home prefix from each action method Route Attribute. The Route
Attribute we define at the Controller level will be applied to each action
method.
The Route template applied on the controller level is prepended to the
route template applied to the action method level. When you navigate to
the following four URLs, you will get the output as expected.
https://localhost:44359/home
https://localhost:44359/home/index
https://localhost:44359/home/details
https://localhost:44359/home/details/10
The following are the Commonly Used Tokens in ASP.NET Core MVC:
[controller]: This represents the controller’s name without the
“Controller” suffix. For example, a controller named HomeController
would have the [controller] token substituted with Home.
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.
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.
The following are the advantages of using Token with Attribute Routing in
ASP.NET Core Web Applications:
Clarity: Route templates with tokens are generally easier to read and
understand, as they directly relate to the controller and action names.
ASP.NET Core MVC – Data Passing Techniques
ViewData in ASP.NET Core MVC Application
ViewBag in ASP.NET Core MVC
TempData in ASP.NET Core MVC
The other three techniques, i.e., ViewBag, Tempdate, and Strongly Typed
View Model, will be discussed in our upcoming articles.
As you can see in the above image, the data type of ViewData Property is
ViewDataDictionary. Let’s look at the definition of the ViewDataDictionary
by right-clicking on it and selecting go to definition, and you will see the
following definition.
@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.
Modifying HomeController:
Next, modify the Home Controller class as shown below. Here, we remove
the existing code and add one action method, i.e., Details. As part of this
method, we create three ViewData objects to store the Title, Header, and
Student data. Here, Title, Header, and Student are the keys of the ViewData
Dictionary Object.
Creating Details.cshtml View:
In our previous article, we discussed the different ways to create Views in
ASP.NET Core MVC Applications. Let us add a view
named Details.cshtml within the Home folder, which is inside
the Views folder, as shown below. Once you add the Details view, your
Views folder structure should look as shown below.
Now open the Details.cshtml view and copy and paste the following code.
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.
In the ASP.NET Core MVC application, we can pass data from a controller to
a view using ViewData, ViewBag, TempData, and a Strongly Typed View
Model.
So, in the ControllerBase class, which is the base class for controllers in
ASP.NET Core MVC, as you can see, there’s a property called ViewBag,
which is a type of DynamicViewData. This DynamicViewData is a dynamic
object that allows properties to be dynamically added at runtime.
Note: The dynamic type is introduced in C# 4.0. It is very similar to the var
keyword, which means we can store any value in it, but the type will be
decided at run time rather than compile time.
How to Access Data from ViewBag in ASP.NET Core MVC with Complex
Type:
The data stored in ViewBag is available only during the current request
lifecycle. Once the view is rendered and sent to the client, ViewBag data is
no longer accessible.
We will work with the same example we worked on in our previous article
with ViewData. So, modify the Details action method of the HomeController
class as shown below.
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.
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.
Type Safety:
ViewBag: It uses dynamic to store data, so there’s no compile-time
type checking. This means you can set and access properties
dynamically, but you may encounter runtime errors if the property
name is mistyped or if the types don’t match.
ViewData: It uses a Dictionary<string, object> to store key-value
pairs. While not type-safe at compile-time, you have to cast values
when retrieving them ((string)ViewData[“Message”]). This provides
slightly more safety compared to ViewBag.
Error Handling:
ViewBag: Due to its dynamic nature, errors like null references or
type mismatches might occur at runtime if not handled carefully.
ViewData: Requires explicit casting when retrieving values, which
can help catch type mismatches earlier.
When to Use:
ViewData: We need to use ViewData when working within loops or
conditional logic where dictionary operations are more
straightforward.
Create a Model
First, you need to define a model class. A model is a C# class with
properties. This class will be used to transfer data between your controller
and view. We will use the same application we used in our previous two
articles. So, we are going to use the same Student model. If you are coming
to this article directly without reading our previous two articles, then
please create the following Student class within the Models folder:
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 is shown below to make the view a
Strongly Typed View.
Then definitely, the question that comes to your mind is how we will pass
the Header and Title to a strongly typed view.
A View Model in ASP.NET Core MVC is a class that represents the data and
logic required by a view. It is specifically designed to serve the needs of the
user interface and does not necessarily map directly to the domain model
or database entities.
The primary purpose of a View Model is to encapsulate all the data that the
view needs to render, making it easier to pass this data from the controller
to the view. It acts as an intermediary between the controller and the view,
encapsulating the data displayed or edited on the view.
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.
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.
Next, create the Address model, representing the Student Address, such
as City, State, Country, etc. So, create a class file with the
name Address.cs within the Models folder and copy and paste the
following code.
Creating the View Model:
Now, create the View Model to store the data required for a particular view.
In our case, it’s the student’s Details view. This View Model will represent
the Student Model + Student Address Model + some additional data like
Page Titles and Headers.
You can create the View Models anywhere in your application, but it is
recommended to create all the View Models within a folder
called ViewModels to keep things organized.
So first, create a folder at the root directory of your application with the
name ViewModels, and then create a class file with the
name StudentDetailsViewModel.cs within the ViewModels folder. Copy
and paste the following code once you create
the StudentDetailsViewModel.cs class file.
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.
TempData in ASP.NET Core MVC serves the purpose of passing data from
one request to the next, specifically between actions or redirects.
The following are some of the common use cases of TempData in ASP.NET
Core MVC Applications:
Passing Data After Redirects: TempData helps to pass data after
redirects, a common requirement in web applications where a
method performs operations and redirects to another method.
Storing Temporary Data: It is useful for storing temporary data that
does not need to be persisted in the database but must be available
across requests.
Message Passing: Commonly used for displaying success or error
messages on action redirects, especially in post-redirect-get patterns.
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.
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.
Keep(string key):
This method retains a specific item in TempData for another request. It is
useful when we have multiple items in TempData but only need to preserve
some of them. Only the TempData entry with the specified key will be
preserved for the next request, while others will be discarded.
Peek(string key)
This method reads an item from TempData without removing it. This is
useful when we need to access the same TempData item across multiple
requests or in multiple places within the same 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.
Privacy.cshtml
About.cshtml
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.
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.
As you can see, we are only fetching the Age key from TempData, not the
Name key, which means the Name key will be preserved in the TempData
dictionary collection for the next request.
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.
If you visit the About page, you will not see the data shown in the image
below.
To preserve the TempData for the next request, use the TempData
Keep or Keep(string) Method. In this case, no matter whether you access
the data or not from the TempData, it will preserve the TempData value for
the next request. 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.
Next, modify the Index.cshtml view as follows. As you can see, we are
fetching both keys from the TempData Dictionary Collection.
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.
How Do We Preserve the TempData for the About Page?
In that case, we need to call the Keep method inside the Privacy Action
method. So, modify the Home Controller as follows:
The key will be deleted from the TempData Dictionary Collection by default
if we read the data using the string Indexer. 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 preserve the key for the
next subsequent request.
With the above changes, run the application and see if everything works as
expected. So, when you run the application, the Index action method will be
redirected to the Privacy Action method. Then, if you visit the About action
method, you will also get the data as expected, as shown in the image
below.
Note: In ASP.NET Core MVC, if we don’t configure any Provider, it will use
the Cookie TempData Provider by default.
Filters are classes that implement one or more filter interfaces, such
as IAuthorizationFilter, IResourceFilter, IActionFilter, IExceptionFilter, IRes
ultFilter. Each filter interface defines a pair of methods that are invoked
before and after a specific stage in the request pipeline.
Let’s delve into the core types of filters available in .NET Core:
The following table summarizes the built-in filters and their use
cases:
Execution Flow of Filters
These methods cannot be directly accessed via a URL, and they do not
return ActionResults.
Action methods are the main entry points for handling HTTP requests
in ASP.NET MVC controllers. They return ActionResults and are
accessible via specific URLs. Non-action methods, on the other hand,
are regular methods within the controller that are not meant to handle
requests directly and are marked as such to prevent accidental
invocation as actions. They are used for encapsulating logic or
functionality that is shared among multiple action methods.
1. ViewResult:
Example:
2. JsonResult:
Example:
3. RedirectResult:
Example:
4. ContentResult:
Represents plain text, HTML, or any content that doesn’t require view
rendering.
5. FileResult:
Example:
6. StatusCodeResult:
Example:
These are some of the commonly used Action Results in ASP.NET Core.
Depending on the desired response and content type, you can choose
the appropriate Action Result type to return from your action methods.
***********************