1 ASP.net Core Basics
1 ASP.net Core Basics
Note: ASP.NET Core was initially launched as ASP.NET 5 but later it was
renamed to ASP.NET Core.
Why ASP.NET Core?
Nowadays, the ASP.NET Core framework becomes more and more popular
among developers. There are a number of reasons why modern developers
are using it and some of them are listed below:
Open Source:
The ASP.NET Core framework is Open Source which is the main reason
behind its popularity. The Entire Source Code of this .NET Core Framework is
available at https://github.com/aspnet and you are free to download the
source code and even if you want then you can also modify and compile your
own version of it.
.NET Core team is always there to support your effort in the seamless
development of the application. It receives bug fixing and improvement
updates on a regular basis usually within a short time period. You don’t have
to wait longer for updates. The flexibility in framework code is keeping it at
the top of the developer’s choice. Depending upon the project’s
requirements libraries and framework’s component can be added later.
Cross-Platform:
The ASP.NET Core Framework is designed from scratch to keep in mind to be
Cross-Platform for both development and deployment. So, we don’t need to
build different applications for different platforms using different frameworks.
Let us discuss what Cross-Platform is from the ASP.NET Core point of view by
comparing it with the earlier versions of the ASP.NET Framework.
The earlier versions of ASP.NET Framework applications can only run on
windows platforms whereas the ASP.NET Core applications can develop and
run on different platforms such as Windows, Mac, or Linux operating
systems. We can host the earlier ASP.NET Framework 4.x applications only
on IIS whereas we can host the ASP.NET Core applications on IIS, Nginx,
Docker, Apache, or even self-host deployment.
To develop ASP.NET Core applications, you have multiple options like you
can use either Visual Studio or Visual Studio Code. If you want, then you can
also use any third-party editors as per your choice.
CLI Support: Using CLI commands you can develop and run .NET
applications as well as you can also publish the application using CLI
command.
Fast: ASP.NET Core no longer depends on System.Web.dll for browser-server
communication. ASP.NET Core allows us to include packages that we need
for the application. This reduces the request pipeline and improves
performance and scalability.
IoC Container: One of the most important used design patterns in the real-
time application is the Dependency Injection Design Pattern. It includes
the built-in IoC (Inversion of Control) container for automatic dependency
injection which makes it maintainable and testable.
Unified MVC and Web API Framework:
The ASP.NET Core provides a unified programming model for developing
both Web apps and Web APIs. That means a single controller class can be
used to handle both. The Controller we create in ASP.NET Core (either Web
APPs or Web APIs) application is going to inherit from the Controller base
class and returns the IActionResult interface. The IActionResult interface
provides several implementations. The built-in result types such as the
JsonResult and the ViewResult and (like this there are so many result types
available that we will discuss later) implement the IActionResult interface.
In the ASP.NET Core Web API application, the controller action method is
going to return JsonResult. At the same time if it is an ASP.NET Core Web
application, then the return type of the controller action method is going to
be ViewResult.
Testing and Maintainability:
You can easily test and maintain the applications developed using the
ASP.NET Core MVC framework. This is possible because it allows you to
separate different parts of your application into independent pieces and it
also allows you to test them independently. The Testing frameworks such as
xUnit and MOQ can be easily integrated into ASP.NET Core MVC application
for simulating any scenario.
Integration with Modern UI Framework: It allows you to use and
manage modern UI frameworks such as AngularJS/Angular, React JS, and
Bootstrap, etc…
Handling Request and Response Pipeline:
We can handle the request and response in the ASP.NET Core application by
using the new Middleware Components. In earlier ASP.NET 4.x we
generally use Handlers and Modules to handle the Request and Response
pipeline. The ASP.NET Core Framework provides a lot of built-in Middleware
Components and we can use those Middleware Components to handle
the request and response pipeline. If you want, then also you can create your
own middleware components and use them in the request-response pipeline.
In a later article, we will discuss the Middleware Components in detail. We
will also discuss how to create custom Middleware Components and how to
use them in ASP.NET Core applications.
Hosting:
ASP.NET Core web application can be hosted on multiple platforms with any
web server such as IIS, Apache, etc… It is not dependent only on IIS as a
standard .NET Framework.
Code Sharing: It allows you to build a class library that can be used
with .NET Frameworks such as .NET Framework 4.x or Mono. Thus, a single
code base can be shared across frameworks.
Side-by-Side App Versioning: ASP.NET Core runs in .NET Core, which
supports the simultaneous running of multiple versions of applications.
Extensible Framework:
The ASP.NET Core MVC Framework is designed to be highly extensible. That
means you can create an application today, that can be extended to any
levels in the future. Some of the key features provided by this framework
that give it the extensible power are as follows.
1. View Components
2. Tag Helpers
3. Routing
In our upcoming articles, we will discuss each of these features in detail.
Smaller Deployment Footprint:
ASP.NET Core application runs on .NET Core, which is smaller than the
full .NET Framework. So, the application which uses only a part of .NET
CoreFX will have a smaller deployment size. This reduces the deployment
footprint.
Excellent developer tools:
ASP.NET Core comes with a lot of preloaded tools. Anybody would love to
work with these tools due to their simplicity and ease. Using JetBrains,
ReSharper, and other tools it very easy to build tests and other extraordinary
applications.
Versatility: Apart from modern web application users can also create
mobile and desktop applications. They can switch whenever they want.
Note: Many people are confused between ASP.NET Core and .NET Core.
Please note that ASP.NET Core and .NET Core are not the same. They are
different, just like ASP.NET and .NET Framework are different. .NET Core is a
fast, lightweight, modular, and open-source framework for creating web
applications, services that run on Windows, Linux, and macOS. So, it is a
software platform on which ASP.NET Core applications run.
What the ASP.NET Core doesn’t have?
If you are coming from ASP.NET 4.x, then you will not find the following
things in ASP.NET Core
1. The Global.asax file
2. Web.Config file
3. HTTP Handlers and HTTP Modules
4. ASP.NET Page Life-Cycle model
.NET Core vs ASP.NET Core:
.Net Core:
1. .NET Core is open-source and cross-platform
2. .NET Core is a runtime to execute applications which ate build on it.
3. Install .NET Core Runtime to run applications and install .NET Core SDK
to build applications.
4. .NET Core 3.1 – latest version
ASP.NET Core:
1. Asp.net core is Open-source and Cross-platform
2. ASP.NET Core is a web framework to build web apps, IoT apps, and
mobile backend on top of .NET Core.
3. There is no separate runtime and SDK are available for ASP.NET
Core. .NET Core runtime and SDK includes ASP.NET Core libraries.
4. ASP.NET Core 3.1 – latest version
5. There is no separate versioning for ASP.NET Core. It is the same as
the .NET Core versions.
Language Support:
Dot Net Core Framework supports the following language i.e. using the
following languages you can develop .NET Core applications. We are going to
use C# as the programming language in this course.
1. C#
2. F#
3. Visual Basic (VB)
.NET Core GitHub Repository:
.NET Core Runtime: https://github.com/dotnet/runtime
.NET Core SDK: https://github.com/dotnet/sdk
ASP.NET Core GitHub
Repository: https://github.com/dotnet/aspnetcore
The Latest version of .NET Core is 3.1 as of today date.
The latest version of ASP.NET Core also is 3.1 as of today’s date.
There is no separate versioning of ASP.NET Core. It is the same as the .NET
Core Versions.
.NET Core is named “Core” because it includes core features of .NET
Framework. The main objective of .NET Core is to make .NET Framework
open-source and cross-platform compatible so that it can be used in
resource-constrained environments. It includes minimum features that are
required to run a basic .NET Core application and other advanced features
that can be as a package from NuGet.
ASP.NET Core Environment Setup
If the .NET Core Framework installed successfully, in your machine, they will
see the version number as shown in the above image.
Download and install .NET Core SDK
If Visual Studio 2019 installer doesn’t include .NET Core 3.x then you need to
install it separately. The ASP.NET Core is a part of .NET Core SDK, so you
don’t require to install it separately. To download the later version of .NET
Core i.e. 3.1 as of today date, go to the following website and select the
platform you are using.
https://dotnet.microsoft.com/download
Once you visit the above page, you will find the following. Here you will find
two things as shown in the below image
As you can see, when we select the Windows option, then we have two
options to develop .NET Core Application i.e. .NET Core 3.1 and .NET
Framework 4.8. As you can see in the above image, .NET Core is a cross-
platform of .NET for building websites, services, and console apps. On the
other hand, .NET Framework is a Windows-only version of .NET for building
any type of app that runs on Windows only. Here we are going with .NET
Core 3.1 which is the latest version of .NET Core Framework as of this
writing.
Further, in .NET Core there are three options are as follows:
.NET Core Runtime: The .NET Core Runtime is required only to run .NET
Core applications. The .NET Core Runtime just contains the resources or
libraries which are required to run existing .NET Core applications.
.NET Core SDK: If you want to develop and run the .NET Core application,
then you need to download the .NET Core SDK. The .NET Core SDK contains
the .NET Core Runtime. So, if you installed the .NET Core SDK, then there is
no need to install .NET Core Runtime separately.
All .NET Core downloads: If you want an older version of .NET Core, then
you need to click on this link and it will navigate to another page, from where
you can download the .NET core Framework version as per your choice as
shown in the below image.
As we are going to set up a development environment for developing and
running .NET Core Applications, so, we need to install .NET Core SDK.
Click on the Download .NET Core SDK button to download the latest
version of .NET Core SDK. It will download the .NET Core 3.1 SDK as of this
writing. After downloading the installer, click on it to start the installation.
Verify the installation
Once you install.NET Core SDK then again you can verify the same using the
command prompt. Open Command Prompt and type dotnet –
version command and press enter. If the .NET Core Framework installed
successfully, in your machine, then you will see the version number as
shown in the above image.
Creating ASP.NET Core Web Application
So, let us discuss a little about all these project templates. In our upcoming
articles, we will use and build the ASP.NET Core Web application using all
these project templates.
Empty Project Template:
As the name says, the Empty Project Template does not have any content by
default. If you want to do everything manually from scratch, then you need
to select the Empty Template. The following image shows the structure of an
Empty template.
API Template:
The API template contains everything that is required and necessary to
create an ASP.NET Core RESTful HTTP service. The following image shows
the structure of an API template.
As you can see from the above image, it contains only the Controllers folder.
The website-specific things such as CSS files, JavaScript files, view files,
layout files, etc. are not present. This is because an API does not have any
user interface hence it does not include such website-specific files. This API
template also does not have the Models and Views folder as they are not
required for an API.
Web Application Template
The Web Application Template uses the new Razor Pages framework for
building web applications. With new Razor Pages, the coding page-focused
scenarios are much easier and more productive. We need to use this
template when we want to develop a web application but do not want the full
complexity of ASP.NET MVC. The following image shows the structure of the
Web Application template.
Once you click on the Next button, it will open the Configure Your New
Project window. Here, you need to give the project name, the location
where you want to create this project, and the solution name. In this
example, let us give the name as “FirstCoreWebApplication” (you can
give any name as per your choice) and click on the Create button as shown
in the image below.
Once you click on the create button, it will open the “Create a new
ASP.NET Core Web Application” window. Here, you need to select the
Empty Template. Also, make sure that you have selected the.NET Core and
ASP.NET Core versions (latest 3.1). Make sure to uncheck all the checkboxes
from the Advanced section and finally click on the Create button as shown
in the below image.
Once you click on the Create button, it will create a new ASP.NET Core Web
Project in Visual Studio 2019.
Changes in the Project file in ASP.NET Core Application:
The ASP.NET Core Project File does not contain any references for folder or
file. In previous versions of ASP.NET Framework, when we add a folder or a
file to the project using Solution Explorer, then a reference to that folder or
file is added in the project file. But with ASP.NET Core, the Project File does
not include any reference for the Files or Folders added the project using
Solution Explorer.
Another significant change in ASP.NET Core is, the File System determines
what folders and files belong to the project. Generally, the files and folders
which are present at the project root folder are part of the project. Those
files and folders which are present at the project root folder are only going to
display in the Solution Explorer.
So, if you add a file or a folder using the File Explorer, then that file or folder
is part of the project. As soon as you add a file or folder using the file
explorer, it immediately displayed in the solution explorer. In the same way,
if you delete a file or folder from the Project Folder or any of its subfolders,
then that deleted file or folder is no longer part of the project and that is
reflected immediately in the Solution Explorer. And the vice-versa is also
true.
How we can Edit the Project File in Previous Versions of ASP.NET:
In our previous versions of ASP.NET Framework, in order to edit the project
file, we need to follow the below steps
1. First, we need to unload the project
2. Then we need to edit the project file
3. Once we edit the file then we need to save the project file
4. Then reload the project.
But with ASP.NET Core we can edit the project file without unloading the
project.
How we can Edit the ASP.NET Core Project File:
ASP.NET Core 1.0 does not create a .csproj file, instead, it uses .xproj and
project.json files to manage the project. This has changed in ASP.NET Core
2.0. Visual Studio now uses the .csproj file to manage projects. To edit the
ASP.NET Core project file, right-click on the project name in the Solution
Explorer, and then select “Edit Project File” from the context menu as
shown in the below image.
Once you click on the “Edit Project File” then the Project file will open in the
Visual Studio editor as shown in the below image.
Understanding the ASP.NET Core Project File:
Let us understand the ASP.NET Core Project File elements.
TargetFramework:
The TargetFramework element in the project file is used to specify the target
framework for your application. To specify the target framework in the
project file it is using something called Target Framework Moniker (TFM).
In our example, the application targets the framework netcoreapp3.1. The
netcoreapp3.1 is the Moniker for .NET Core 3.1. If you remember, we created
this project with .NET Core 3.1.
Adding Packages in ASP.NET Core:
As we already discussed ASP.NET Core Framework follows modular
approaches. It means by default it will not include anything i.e. packages
references to the project. Only the necessary packages which are required
are added.
Whenever we add any new packages into our application, then that
packages reference is also going to be added into the application project file.
Please have a look at the following Dependencies section. Whenever we add
any packages, then that package and its dependency packages are going to
be stored here.
Let us first add a package from the NuGet Package Manager and see what
happens. Go to tools => NuGet Package Manager => Manage NuGet
Packages for Solution option as shown in the below image.
Now let us add the Newtonsoft.json package. So, select the browse tab and
then search Newtonsoft and install it as shown in the below image.
Once the package is installed successfully, then you will see, it will add the
reference inside the dependencies section as shown in the below image.
As we have only added one package i.e. Newtonsoft.json, so it added that
package references here. Along with the same, it will also add that package
reference in the application project file as shown in the below image.
Note: Once you delete that package, then it will delete the reference from
both the dependencies as well as from the project file.
Deleting Package in ASP.NET Core:
Again, go to the Nuget Package Manager and select the installed tab and
select the package and uninstall it as shown in the below image.
Once you delete the package, then it should remove the reference from both
the dependencies as well as from the project file. The Package Reference
element of the project file is used to add the references to all the NuGet
packages which are installed for your application.
Note: The csproj file includes settings related to targeted .NET Core
Framework, project folders, NuGet package references, etc…
Once you click on the create button, it will open the Create a new ASP.NET
Core Web Application window. Select the Empty Project template and
uncheck all the checkboxes from the Advanced section and finally click on
the Create button as shown in the below image.
Once you click on the Create button, it will take some time and will create
the Empty ASP.NET Core Web Application with the following file and
folder structure.
As you can see from the above image, we have a class file with the
name Program.cs. The Program.cs class file of our ASP.NET Core Web
Application contains the following code.
From the above image, you can see that the Program class contains a public
static void Main() method. As we already know, when we create a console
application in .net then by default the .NET Framework creates a class (i.e.
Program class) with the Main Method. We also know that the Main method is
the entry point for that console application execution.
Now the question is, here we are not creating a console application, here we
create an ASP.NET Core Web Application. Then why do we have a Main()
method in the ASP.NET Core Web Application?
Why do we have a Main() method in ASP.NET Core?
The most important point that you need to keep in mind is, the ASP.NET Core
Web Application initially starts as a Console Application and the Main()
method is the entry point to the application. So, when we execute the
ASP.NET Core Web application, first it looks for the Main() method and this is
the method from where the execution starts. The Main() method then
configures ASP.NET Core and starts it. At this point, the application becomes
an ASP.NET Core web application.
If you further look at the body of the Main() method, then you will find that it
makes a call to the CreateHostBuilder() method by passing the command
line arguments args as an argument as shown in the below image.
As shown in the below image, the CreateHostBuilder() method returns an
object that implements the IHostBuilder interface. The Host is a static class
that can be used for creating an instance of IHostBuilder with pre-configured
defaults. The CreateDefaultBuilder() method creates a new instance of the
HostBuilder with pre-configured defaults. Internally, it configures Kestrel
(Internal Web Server for ASP.NET Core), IISIntegration, and other
configurations.
Within the Main() method, on this IHostBuilder object, the Build() method is
called which actually builds a web host. Then it hosts our asp.net core web
application within that Web Host. Finally, on the web host, it called the
Run()method, which will actually run the web application and it starts
listening to the incoming HTTP requests.
The CreateHostBuilder() method calls the static CreateDefaultBuilder()
method on the Host class. The CreateDefaultBuilder() method creates a web
host with the default configurations. Behind the scene, to create a host, the
CreateDefaultBuilder() method does several things. In the next article, we
will discuss the CreateDefaultBuilder() method in detail. For now, just
understand that the CreateDefaultBuilder() method sets up a web host with
default configurations.
Startup Class
While setting up the host, the Startup class is also configured using
the UseStartup() extension method of the IHostBuilderclass. The Startup
class has two methods as shown in the below image.
The ConfigureServices()method of the Startup class configures the services
which are required by the application. The Configure() method of the Startup
class sets up the pipeline of the application’s request processing. In a later
article, we will discuss these two methods in detail.
When we execute an ASP.NET core application then the .NET Core runtime
looks for the Main() method. The Main() method is the entry point for the .net
core application to execute.
As you can see from the above image the Main() method of the Program
class calls the static CreateHostBuilder() method. Then
the CreateHostBuilder() method calls the
static CreateDefaultBuilder()method on the Host class.
The CreateDefaultBuilder() method sets the web host which will host our
application with default preconfigured configurations.
What are the Tasks performed by CreateDefaultBuilder() method?
As part of setting the web host, the CreateDefaultBuilder() method does
several things. Some of them are as follows
1. Setting up the webserver (will discuss in this article)
2. Loading the host and application configuration from various
configuration sources (will discuss in our upcoming articles)
3. Configuring logging (will discuss in our upcoming articles)
Let us discuss what exactly the CreateDefaultBuilder() method does to
configure and set up the webserver. From a hosting point of view, an
ASP.NET core Web application can be hosted in two ways
i.e. InProcess hosting or OutOfProcess hosting.
Here in this article, we are going to discuss the InProcess hosting model and
in a later article, we will discuss the OutOfProcess hosting model.
Note: When we create a new ASP.NET Core Web application by using any
template, by default the project file is created with InProcess hosting which
is used for hosting the application in IIS or IIS Express scenarios.
How to verify this?
In order to verify the same, open the project properties. Right-click on your
project and select the properties option from the context menu. Once you
open the properties window, then select the Debug and have a look at the
value of the Hosting Model drop-down list as shown in the below image. The
drop-down list contains three values i.e. Default (InProcess), InProcess, and
Out Of Process. In our upcoming articles, we will discuss the Out Of Process
hosting model.
You are getting the above message from the following Startup class
To display the process name in the browser you need to use
the System.Diagnostics.Process.GetCurrentProcess().ProcessName w
ithin the Startup as shown below. In our upcoming article, we will discuss the
Startup class in detail. For now, just copy-paste code.
namespace FirstCoreWebApplication
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to
the container.
// For more information on how to configure your application, visit
https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the
HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Worker Process Name : " +
System.Diagnostics.Process.GetCurrentProcess().ProcessName);
});
});
}
}
}
Now when we run the application from visual studio, and it should display the
message in the browser as shown below.
Once you select the FirstCoreWebApplication, now run the application. Here,
we need to observe two things. First, it will launch the command prompt and
host the application using the Kestrel server as shown below. Here, you need
to focus on the URL and port number and it should be the URL and port
number mentioned in your FirstCoreWebApplication profile of
launchSettings.json file.
Secondly, it opens the default browser and listening to that URL and Port
Number as shown below.
Note: In our example, for IIS Express the port number is 60211, and worker
process is iisexpress while for Kestrel server the port number is 5000 and the
worker process name is FirstCoreWebApplication (It is nothing but your
application name).
How to run .NET Core application using .NET Core CLI?
We can also run the ASP.NET Core application from the command line using
the .NET Core CLI. The CLI stands for Command Line Interface.
When we run an ASP.NET Core application using the .NET Core CLI, then
the .NET Core runtime uses Kestrel as the webserver. We will discuss
the .NET Core CLI in detail in our upcoming article. Now, let us see how to
run a dot net core application using .NET Core CLI Command.
First. open the command prompt and type “dotnet —” and press enter as
shown below.
Once you type the “dotnet —” and click on the enter button then you will
find lots of commands as shown below.
Using the CLI (above commands)
You can create a new project using the new command, you can also build
the project using the build command, or you can publish the project using
the publish command. It is possible to restore the dependencies and tools
which are required for a .net core project using the CLI.
Running .NET Core application using .NET Core CLI
Let’s see how to run a .NET Core application using .NET Core CLI command.
To do so please follow the below steps
First, open the Windows Command Prompt. To do so, open the run window
and then type cmd and click on the enter button which will open the
command prompt. Then you need to change the directory to the folder which
contains your asp.net core application. My project is present in the “D:\
Projects\Core\FirstCoreWebApplication\FirstCoreWebApplication”
folder so I change the current directory to my project file by using the
following command.
Once you change the directory to your project folder, then execute the
“dotnet run” command as shown in the below image.
Once you type the dotnet run command, press the enter key, then the .NET
Core CLI builds and runs the application. It also shows the URL and you can
use this URL to access your application as shown in the below image.
Now, save the changes and run the application using Kestrel Server and you
should see the changed port number in the URL.
To confirm this, open the command prompt and run the application as shown
in the below image. As my First, you need to change the directory to the
folder which contains your asp.net core application. My project is present in
the “D:\Projects\Core\FirstCoreWebApplication\
FirstCoreWebApplication” folder so I change the current directory to my
project file and then use the dotnet run command.
Once you type dotnet run command and press the enter key, it will build,
host, and run the application as shown in the below image.
Now open the browser window and navigate to the following URL which is
shown in the command prompt. In my case, the following is the.
http://localhost:5000
And here you will see the worker process name as your application name as
shown below
So, in this case, Kestrel is the only server that will handle and process the
incoming HTTP Request. The following code of the Startup class displays the
worker process name.
namespace FirstCoreWebApplication
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to
the container.
// For more information on how to configure your application, visit
https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the
HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Worker Process Name : " +
System.Diagnostics.Process.GetCurrentProcess().ProcessName);
});
});
}
}
}
Way2:
The Kestrel Web Server can also be used with the combination of a reverse
proxy server such as IIS, Apache, or Nginx. Now the question that should
come to your mind is, If Kestrel can be used by itself as a web server which
can directly handle and process the incoming HTTP Request, then why do we
need a reverse proxy server?
This is because the reverse proxy server provides an additional layer of
configuration and security which is not available with the Kestrel Server. It
also maintains the load balancing. So, it is a good choice to use Kestrel
Server along with a reverse proxy server.
So, when we use Kestrel Server along with a reverse proxy server, then the
reverse proxy server will receive the incoming HTTP requests from the client
and then forwards that request to the Kestrel server for processing. Once the
Kestrel Server process that request, then it sends the response back to the
reverse proxy server which then sends the response back to the requested
client over the internet as shown in the below image.
In our upcoming articles, we will discuss how to deploy an ASP.NET Core
application to IIS and how we can use IIS as a reverse proxy server.
When we run the application directly from Visual Studio, then by default
Visual Studio uses IIS Express. Now change the AspNetCoreHostingModel
element value as shown below in the application’s project file.
<AspNetCoreHostingModel>OutOfProcess</
AspNetCoreHostingModel>
As we have configured the Out of Process hosting model, now the IIS Express
acts as a reverse proxy server and Kestrel acts as the internal webserver.
Now, the IIS Express receives the incoming HTTP request and then forwards
it to the Kestrel Web Server for processing. The Kestrel Web Server
processes the request and sends the response back to the IIS Express which
in turn sends the response back to the client i.e. to the browser.
Now run the application, and you will see the worker process as your project
name. So, when you are using Out of Process Hosting model, then the
Kestrel Web Server is going to hosts the application and process the request
irrespective of whether you are using a reverse proxy server or not.
What happens when we run the ASP.NET Core application
using .NET Core CLI?
When we are running our application using.NET Core CLI, then by default, it
ignores the hosting setting that you specified in the application’s project file
i.e. csproj file. So, in that case, the value of the AspNetCoreHostingModel
element is going to be ignored.
The .NET Core CLI always uses OutOfProcess Hosting Model and Kestrel is
the webserver that will host the ASP.NET Core application and also handles
the HTTP requests.
Can we run an asp.net core application without using the built-in
kestrel web server?
YES. When we use the InProcess Hosting model, then the application is
hosted inside the IIS worker process i.e. w3wp.exe in the case of IIS and
iisexpress.exe in the case of IIS Express. That means the Kestrel Web Server
is not used with the InProcess hosting model.
Once you click on the Create a new project box, then it will open the Create a
new project window. From this window, you need to select the ASP.NET
Core Web Application template and then click on the Next button as
shown in the below image.
Once you click on the Next button, then it will open the “Configure Your New
Project” window. Here, you need to give the name for your project, set the
location of your project, give the solution name. In this example, I will give
the name “FirstCoreWebApplication” and then click on the Create button
as shown in the image below.
Once you click on the create button, then it will open the Create a new
ASP.NET Core Web Application window. From this window, you need to select
the Empty Project template and uncheck all the checkboxes from the
Advanced section. Please make sure to select .NET Core and ASP.NET Core
3.1 from the respective dropdown list and finally click on the Create button
as shown in the below image.
Once you click on the Create button, it will take some time and will create
the Empty ASP.NET Core Web Application with the following file and folder
structure.
As you can see from the above image, the ASP.NET Core Project has a file
called launchSettings.json within the Properties folder. So, let us discuss
the need and importance of this launchSettings.json file in the ASP.NET
Core application.
Understanding LaunchSettings.json file in ASP.NET Core
The settings that are present within this file are going to be used when we
run the .NET core application either from Visual Studio or by using .NET Core
CLI.
The most important point that you need to keep in mind is this
launchSettings.json file is only used within the local development machine.
That means this file is not required when we publishing our asp.net core
application to the production server.
If you have certain settings and you want your application to use such
settings when you publish and deploy your asp.net core application to the
production server, then you need to store such settings in the
appsettings.json file. Generally, in the ASP.NET Core application, the
configuration settings are going to be stored in the appsettings.json file. In
our upcoming article, we will discuss the appsettings.json file in detail.
ASP.NET Core Application Profile settings in the launchSettings.json
file:
If you open the launchSettings.json file, then by default you will find the
following code or you can say settings within that file in ASP.NET Core 3.1
applications.
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50409",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"FirstCoreWebApplication": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
The point that you need to remember is when you run the application from
Visual Studio either by pressing CTRL + F5 or just F5 then by default the
profile with “commandName”: “IISExpress” is going to be used. On the
other hand, if you run the ASP.NET Core application using .NET Core CLI (i.e.
dotnet run command), then the profile with the “commandName”:
“Project” is going to be used.
However, if you want then you can choose which profile to use when you run
the application by pressing CTRL + F5 or just F5, by clicking on the drop-
down list in Visual Studio as shown below
The value of the commandName property of the launchSettings.json file can
be any one of the following.
1. IISExpress
2. IIS
3. Project
The CommandName property value of the launchSettings.json file along with
the AspNetCoreHostingModel element value from the application’s project
file will determine the internal and external web server (reverse proxy
server) that are going to use and handle the incoming HTTP Requests. For
better understanding, please have a look at the below table.
If you look at the launchSettings.json file, then you will see that
the FirstCoreWebApplication profile uses the “commandName”:
“Project” value, and as well as please focus on the application URL as
shown below. In my application the URL is http://localhost:5000 and the
port number might be varying in your example.
Now, if you run the project either by pressing CTRL + F5 or just F5, first it will
launch the command prompt where it will host the application using the
Kestrel server as shown below.
Once it launches the command prompt and hosts the application, then by
default it opens your default browser and displays the worker process name
as the project name i.e. FirstCoreWebApplication as shown in the below
image. This is because when the CommandName value is Project then it
ignores the AspNetCoreHostingModel value and Kestrel is the only server
that is going to host and process the incoming requests.
That’s it. Run the application and it should display the project name as the
worker process name as shown in the below image as the request is
internally handled by Kestrel Web Server.
The rest two cases we will discuss in a later article when we host the
application using IIS. If you want then you can also change the settings of
the launchSettings.json file using the Graphical User Interface (GUI) provided
by Visual Studio.
How to access the Graphical User Interface (GUI) in Visual Studio?
To do so, right-click on the project name in Solution Explorer and then select
the “Properties” option from the context menu. Once you open the project
properties window, click on the “Debug” tab on the as shown in the below
image.
Using the Graphical User Interface, you can also change the settings of
the launchSettings.json file. Now here you can see that the Environment
Variable “ASPNETCORE_ENVIRONMENT” is set to “Development”. You
can change this Environment Variable value
to Staging or Production depending on where you are running your
application.
If you want, then you can also add new environment Variables. These
environment variables are available throughout your application. And if you
want then you can also execute some code conditionally depending on the
environment variables value. For example, consider the
following Configure() method of Startup.cs file.
It checks if the environment is Development, then it is going to display the
Developer Exception Page. In our upcoming articles, we are going to discuss
more these environment variables.
As you can see in the code, the Startup class includes two public methods:
ConfigureServices and Configure. The Startup class must include the
Configure method and can optionally include the ConfigureService method.
ConfigureServices() method in ASP.NET Core Startup class
The Dependency Injection pattern is used heavily in ASP.NET Core
architecture. It includes the built-in IoC container to provide dependent
objects using constructors.
The ConfigureServices method is a place where you can register your
dependent classes with the built-in IoC container. After registering the
dependent class, it can be used anywhere in the application. You just need to
include it in the parameter of the constructor of a class where you want to
use it. The IoC container will inject it automatically.
ASP.NET Core refers to the dependent class as a Service. So, whenever you
read “Service” then understand it as a class that is going to be used in some
other class.
The ConfigureServices method includes the IServiceCollection parameter to
register services to the IoC container. For example, if you want to add
RazorPages services or MVC services to your asp.net core application, then
you need to add those services to the parameter this method accepts as
shown in the below image.
As you see from the above output, it fetches the MyCustomValue from the
appsettings.Development.json file. The point that I need to make you clear, if
you have a configuration setting in multiple configuration sources with
the same configuration key, then the later configuration sources will override
the earlier configuration sources.
What are the Default Orders of reading the configuration sources?
The default orders in which the various configuration sources are read for the
same key are as follows
1. appsettings.json,
2. appsettings.{Environment}.json here we use
appsettings.development.json
3. User secrets
4. Environment variables
5. Command-line arguments
We already have MyCustomKey in two places i.e. appsettings.json and
appsettings.development.json. Now add the same key as “MyCustomKey”:
“MyCustomKey Value coming from Environment Variable of
launchsSettings.json” in the IIS Express profile section of the
launchSettings.json file as shown below.
With this change now run the application and it should display the value
coming from the environment variable.
How to Pass Config value from Command Line in ASP.NET Core
Application?
Now open the browser window and type the following URL
As you can see the Main() method of the Program class calls the
CreateHostBuilder() method. Then the CreateHostBuilder() method calls the
CreateDefaultBuilder() method on the Host class. This CreateDefaultBuilder()
method is the method that sets the default order in which all the
configuration sources are read.
If you want then you can also change this default order or even if you want
then you can add your own custom configuration sources along with the
existing configuration sources. In our upcoming articles, we will discuss
setting up a custom configuration source.
So, whenever you want to configure any middleware components in any type
of .net core applications, then you need to configure it within the Configure()
method of the Startup class by calling the Use* methods on the
IApplicationBuilder object. As you can see in the above image, the
Configure() method sets up the request processing pipeline with just three
middleware components are as follows.
1. UseDeveloperExceptionPage() Middleware component
2. UseRouting() Middleware component
3. UseEndpoints() Middleware component
Before understanding the above three built-in Middleware components. Let
us first understand what are Middleware components and how exactly these
Middleware components work in an ASP.NET Core application.
Understanding Middleware Components in ASP.NET Core:
In the ASP.NET Core application, the Middleware component can have access
to both the incoming HTTP Request and outgoing HTTP Response. So, a
Middleware component in ASP.NET Core can
1. Handle the incoming HTTP request by generating an HTTP response.
2. Process the incoming HTTP request, modify it, and then pass it to the
next middleware component
3. Process the outgoing HTTP response, modify it, and then pass it on to
either the next middleware component or to the ASP.NET Core web
server.
For better understanding, please have a look at the following diagram which
shows how the middleware components used in the request processing
pipeline of an ASP.NET Core application.
Instead of MapGet, you can also use the Map method as shown below.
Now run the application and you should get the output as expected.
What is the difference between MapGet and Map method?
The MapGet method is going to handle the GET HTTP Requests whereas the
Map method is going to handle all types of HTTP requests such as GET, POST,
PUT, & DELETE, etc.
How to Configure Middleware Components using the Run()
extension method?
Let us understand how to create and configure custom middleware
components using the Run extension method. First of all, comment on all
codes which are present inside the Configure method. Once you comment on
the existing code, then copy and paste the following code into the Configure
method. The following code simply adds a new middleware component to the
application’s request pipeline and simply prints a message.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Getting Response from First
Middleware");
});
}
Output:
As you can see from the definition of the Run() method, it is implemented as
an extension method of the IApplicationBuilder interface. This is the reason
why we are able to call the Run() method using the IApplicationBuilder
instance i.e. app. If you are new to the extension method then please read
the below article where we discussed the extension methods in detail.
https://dotnettutorials.net/lesson/extension-methods-csharp/
You can also see from the above image that the Run() method takes an input
parameter of type RequestDelegate. Following is the definition of
RequestDelegate.
As you can see from the above image, the RequestDelegate is a delegate
that takes an input parameter of type HttpContext object. If you are new to
delegates then I strongly recommended you read the following article where
we discussed the delegates in detail.
https://dotnettutorials.net/lesson/delegates-csharp/
As we already discussed the middleware components in the ASP.NET Core
application can have access to both HTTP Request and Response and this is
because of the above HttpContext object.
In our example, we are passing the request delegate inline as an anonymous
method using lambda expression and moreover, we are passing the
HTTPContext object as an input parameter to the request delegate. The
following diagram shows the above
Now run the application and you will see the output as expected which is
coming from both the middleware components.
Understanding the Use extension method:
The Use extension method adds a middleware delegate defined in-line to the
application’s request pipeline. Following is the definition of the Use extension
method:
Now run the application and see the browser window as shown in
the below image.
With the above changes in place, now the MyWebRoot folder is going to act
as the Webroot folder for your application and can serve the static files HTTP
requests.
Once you created the wwwroot folder, let’s add an Image file within that
folder. Please download and paste the following image into the wwwroot
folder and modify the image name as MyImage.png.
Once you the above image, your wwwroot directory looks as shown below.
Now run the application and navigate to the following URL. The point that
you need to remember is you need to replace the port number on which your
application is running.
http://localhost:<portnumber>/MyImage.png
When you navigate to the above URL, you will not get the output as
expected, rather than you will get the following output.
The reason why we are not getting the output as expected because we don’t
have any middleware which can serve the static files in the request
processing pipeline.
How to Configuring the Static Files Middleware in ASP.NET Core
Application?
In order to handle the static resources, we need to configure a
middleware called UseStaticFiles() into the application request processing
pipeline of an ASP.NET Core Application. The UseStaticFiles() middleware is
an inbuilt middleware provided by ASP.NET Core Framework to handle the
static files in an ASP.NET Core Application.
Let us Modify the Configure() method of the Startup class as shown below in
order to add the UseStaticFiles() middleware to the request processing
pipeline of the application.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//Adding Static Files Middleware to serve the static files
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
}
With the above changes in place, now run the application and navigate to
the URL: http://localhost:<portnumber>/MyImage.png and you will see
the output as expected as shown in the below image.
How to Create your own Webroot folder in ASP.NET Core?
Let say we don’t want wwwroot as our webroot folder instead we want
MyRoot as the webroot folder for our application. First. Modify the wwwroot
folder as MyRoot and once you modify your project structure should be as
shown below.
At this point, if you run the application and if you navigate to the below URL,
then you will not get the output.
http://localhost:<portnumber>/MyImage.png
This is because by default the static files middleware will look for a folder
with the name wwwroot and that is not present in our application at the
moment. But we don’t want wwwroot, we want the Static files middleware to
look MyRoot folder to the server the static files such as CSS, Images, JS, etc.
To do so, we need to call the UseWebRoot method by passing MyRoot as a
parameter in the CreateHostBuilder method which available in the Program
class as shown below.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>().UseWebRoot("MyRoot");
});
}
With the above changes in place, now run the application and you should get
the output as expected.
Now, open the index.html file which is present inside the wwwroot folder
and then copy and paste the following code in it.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1> This is Index HTML File</h1>
</body>
</html>
Now, if you remove index.html from the URL or navigate to the base URL,
then the request is going to be handled by the terminating middleware which
is registered using the Run method. That the default request is going to be
server by the Run method as shown below.
But what we want is, when we navigate to the base URL as shown above, we
want our index.html page to serve the request. That is, we need to set the
index.html page as our default page.
Setting the Default Page in ASP.NET Core Application:
Most of the web applications have a default page such as index.htm(l) or
default.htm(l) as their startup page as it is easy to remember. This is the web
page that is going to be displayed when a user visits the root URL of that
application. For example, if you have a page with the name index.html and
you want that page to be your default page so that whenever any user visits
your root URL, then that page is going to be displayed.
In order to serve the index.html page which is present inside the wwwroot
folder as the default page of your application, you need to add another
middleware i.e. UseDefaultFiles() middleware into the request processing
pipeline.
So, modify the Configure() method of the Startup class as shown below to
use the UseDefaultFiles() middleware which will set the default page for
your application.
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//Setting the Default Files
app.UseDefaultFiles();
//Adding Static Files Middleware to serve the static files
app.UseStaticFiles();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Request handled by the terminating
middleware");
});
}
}
With the above changes in place, now run the application and you should the
output as expected as shown below. That index.html page serves as your
default page.
Now run the application and you will see the output as expected that
is coming from the MyCustomPage1.html file as shown below. If you still see
the output from the index.html page then it may be due to cache so just try
to reload the page. If still, you are not getting the data from the
MyCustomPage1.html file then just restart the visual studio.
Now run the application and you will see the output as expected.
When you run the application, you will get the following output.
As you can see in the above image it gives you the status code as 500 which
means Internal Server Error. But as a developer when you are developing the
application, you should know the detailed information about the exception on
the page so that you can take necessary actions to fix the error. And this
where DeveloperExceptionPage Middleware comes into the picture.
How to use DeveloperExceptionPage Middleware in ASP.NET Core
Application?
If you want your application to display a page that shows the detailed
information about the unhandled exception, then you need to configure the
Developer Exception Page middleware in the request processing pipeline. To
do so, modify the Configure() method of the Startup class as shown below to
add the Developer Exception Page middleware which will handle the
unhandled exception that occurred in your application.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
throw new Exception("Error Occurred while processing your request");
await context.Response.WriteAsync("Hello World!");
});
});
}
With the above change in place, now run the application and it should
display the following page with the detailed information about the unhandled
exception.
As you can see in the above image, the Developer Exception Page contains
five tabs such as Stack, Queue, Cookies, Headers, and Routing.
1. Stack: The Stack tab gives the information of stack trace which
indicated where exactly the exception occurred, the file name, and the
line number that causes the exception.
2. Query: The Query tab gives information about the query strings.
3. Cookies: The Cookies tab displays the information about the cookies
set by the request.
4. Header: The Header tab gives information about the headers which is
sent by the client when makes the request.
5. Route: The Route tab gives information about the Route Pattern and
Route HTTP Verb type of the method, etc.
Now if you verify the Query tab and Cookies tab, then you will not see any
information as you are not passing any query string value in the URL or you
are not setting the cookies in the request. In our upcoming articles, we will
discuss the Query string and Cookies in detail.
Note: Please Enable the Developer Exception Page Middleware only when
the application is running in the Development environment. You don’t want
to share detailed exception information when the application is running in
the production environment.
How to Customize the UseDeveloperExceptionPage Middleware in
ASP.NET Core?
If you want then you can also customize the UseDeveloperExceptionPage
middleware. The point that you need to remember is whenever you want to
customize a middleware component in ASP.NET Core then you need to use
the respective Options object. For example
1. UseDeveloperExceptionPage => to customize this middleware use
DeveloperExceptionPageOptions object
2. UseDefaultFiles => to customize this middleware use
DefaultFilesOptions object
3. UseStaticFiles => to customize this middleware use
StaticFileOptions object
4. UseFileServer => to customize this middleware use
FileServerOptions object
As we are going to customize the
UseDeveloperExceptionPage() middleware component, so we need to use
the DeveloperExceptionPageOptions object. So, modify the Configure
method of the Startup class as shown below.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
DeveloperExceptionPageOptions developerExceptionPageOptions = new
DeveloperExceptionPageOptions
{
SourceCodeLineCount = 5
};
app.UseDeveloperExceptionPage(developerExceptionPageOptions);
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
throw new Exception("Error Occurred while processing your request");
await context.Response.WriteAsync("Hello World!");
});
});
}
As you can see in the above code, we are using one property
called SourceCodeLineCount. The SourceCodeLineCount property of
the DeveloperExceptionPageOptions class specifies the number of lines
of code to include before and after the line of code that caused the
exception.
Now if you run the application with the above changes in place, then you will
get the following error. Please have a look at the line number of the error i.e.
39. And also please look at the numbers of lines before and after the error
line.
This will add the Newtonsoft.json package to your project. You can verify the
same in the project file. So, open .csproj file and you should get the
following.
Remove Package Reference using .NET Core CLI Command:
The “dotnet remove package” command provides a convenient option to
remove a NuGet package reference from a project. If you want to remove the
NuGet Package that we just installed Newtonsoft.json then you need to
execute the below command,
dotnet remove package Newtonsoft.json
So, in the command prompt and type “dotnet remove package
Newtonsoft.json” and press enter as shown in the below image which will
remove the Newtonsoft.json package from your project and you verify the
same in the project file.