Configuring Application in ASP.NET Core MVC

Configuring Application in ASP.NET Core MVC

This tutorial on ASP.NET Core MVC Configurations will reveal you a lot about the inside of this framework. This will give you a solid foundation for understanding the coming topics later on. I will start by creating a new project using empty template.

Create Project using Empty Template

When you create a project using Empty Template you have to do the configurations by yourself. This includes:

1. Adding Folders for Controllers, Views & Models.
2. Adding Configuration files like appsettings.json, bower.json, etc.
3. Adding the layout View.

And many more things which you will see in this tutorial.

In your Visual Studio select File ➤New ➤ Project, then on the New Project dialog box click the Installed ➤ Visual C# ➤Web link, given on the left side.

You will see the option – ASP.NET Core Web Application, select it and specify the location on your drive where you want the application to be created. Give the name of your application as ‘Configuation’.

Then finally click the ‘OK’ Button.

create new project in vs 2017

Now you will get another dialog box where you can select the Framework, Version, Template and Authentication. You should select:

1) .NET Core
2) ASP.NET Core 2.0
3) Empty (for template)
4) No Authentication

asp net core empty template

This will create your ASP.NET Core MVC with Empty Template.

What is .csproj

The .csproj file which in your application will be configuration.csproj.

This file is hidden by Visual Studio and must be accessed by right clicking your project and select ‘Edit Configuration.csproj’.

csproj file

The initial context of the Configuration.csproj file is shown below:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
  </ItemGroup>

</Project>

The csproj contains many settings which are used to build .NET Projects. You can add any package that your application needs to this file. When you any package to the csproj file then Visual Studio downloads that package similarly when you remove any package from csproj file then Visual Studio removes that package from your application.

The elements in csproj files
Element Description
Project It is the root element, the Sdk attribute specifies that the application should be build with Microsoft.NET.Sdk.Web package.
PropertyGroup Used to group related properties.
TargetFramework Instructs .NET Core to use the specified version when building a project.
ItemGroup Used to group related items.
Folder It tells .NET Core to include the folder (here wwwroot) when publishing the project.
PackageReference It specifies dependency on the NuGet package which here is Microsoft.AspNetCore.All version 2.0.5. The Microsoft.AspNetCore.All is a package providing access to all individual packages which provides ASP.NET Core and MVC functionalities.

Json.NET is a popular high-performance JSON package for .NET. It is used to serialize and deserialize JSON. To add Json.NET packages add the below ItemGroup in your csproj file:

<ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

As soon as you save the csproj file, VS will download the Json.NET package and add it to your project.

Typing package names and there versions on the csproj file can be error prone. You can avoid this typing completely by adding packages through NuGet Package Manager.

Adding Packages through NuGet

NuGet Package Manager allows for the management of NuGet packages through an easy-to-use interface. Select Tools ➤ NuGet Package Manager ➤ Manage NuGet

Packages for Solution in your Visual Studio. This will opens NuGet Solution dialog box, there click the Browse tab and enter the name of package in the text box. When you see you searched package on the list, select it and then click the ‘Install’ button.

In the below image I have searched for Json.NET, and then selecting and installing it.

adding json net package nuget

There is a shorter way too if you know the name of the package you require (and, ideally, the version). This way is through Package Manger Console. Select Tools ➤ NuGet Package Manager ➤ Packages Manager Console in your Visual Studio then enter the below line (and press enter key) to install the Json.NET package.

PM> Install-Package Newtonsoft.Json

The Program Class

On the root folder of your application you will find the Program.cs which is called the Program Class. It has a Main() function that provides the entry point for running the application.

The default code of the Program Class is shown below:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Configuation
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

The Main method in the Program class calls a BuildWebHost() function, which configures the ASP.NET Core like setting up the hosting environment.

Inside the BuildWebHost() function, you will find it calling the CreateDefaultBuilder() function which configures the application with the Most Suitable Settings. By ‘Most Suitable Settings’ I mean the settings are suitable for most of the ASP.NET Core applications.

The UseStartup() function calls the Startup.cs class which is also kept on the application root folder. The Startup.cs class provides application specific configuration. In the coming section you will learn more about Startup Class.

The Build() function builds the application and if no errors are found then will run your application on the browser.

Inside the BuildWebHost() function you can provide individual configuration settings. In the below code I have provided 3 individual settings:

public static IWebHost BuildWebHost(string[] args)
{
    return new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup<Startup>()
    .Build();
}

These Individual settings are:

Name Description
UseKestrel() Configures the Kestrel web server.
UseIISIntegration Enables integration with IIS and IIS Express.
What is KESTREL Web Server?

Kestrel is an open-source, cross-platform web server for hosting ASP.NET applications on any platform. It is used automatically when running ASP.NET Core application with IIS.

You can use Kestrel by itself or with a reverse proxy server, such as IIS, Nginx, or Apache. A reverse proxy server receives HTTP requests from the Internet and forwards them to Kestrel after some preliminary handling.

In order to use Kestrel by itself, for running ASP.NET Core MVC application on any of the supported platforms, you click the arrow on the right of IIS Express button in your VS then select the option that says the name of your application. In this application it will be ‘Configuration’.

select Kestrel in visual studio

Once selected the name of your application you have to run your application (shortcut F5 key). Now your application will now run on Kestrel only.

The Startup Class

You will find the Startup.cs file on your application’s root folder. This file is the Startup class. The Program Class calls the Startup Class using UseStartup() function. In the startup class you can provide a lot of application specific configuration which you will see in the coming sections.

If you open the Startup class you will see it like shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Configuation
{
    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, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
}

The Startup Class contains 2 methods – ConfigureServices() and Configure().

In the ConfigureServices() method you can create one or more services that can be used through your application. A service can be anything that do a task and is available throughout the application. In the below section I will create a simple service to help you understand them in a better way.

In the Configure() method you can configure HTTP Request pipeline which is also know by the name middleware. I will also create some middleware later on.

In the current code, when you run the application it will just sent the response text – ‘Hello World!’ on the browser for all requests.

startup class

Understanding Services in ASP.NET Core MVC

A Service can be anything in ASP.NET Core which does a particular task and is available all through the application. Examples like:

1. A Service for sending a text verification code to user’s email address.
2. A Service for validating mobile number through OTP.
3. A Service that helps in recovering the user’s account password when lost.

Here I will create a small ASP.NET Core Service that provides the application with the total number of registered users.

Start by creating a folder in your application’s root folder and name it ‘Services’ or anything you like. Inside this ‘Services’ folder create a class and name it ‘TotalUsers.cs’ and add the following code to it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Configuation.Services
{
    public class TotalUsers
    {
        public long TUsers()
        {
            Random rnd = new Random();
            return rnd.Next(100, int.MaxValue);
        }
    }
}

This class has one public method – Tusers() which returns the total number of users registered in the application. Here it just returns a random number between 100 and max value of Int. In a real application you are going to fetch this value from the database

The next step involves registering this TotalUsers class in the Startup.cs class so that ASP.NET Core can make this service available through the application.

So go the Startup.cs class and import the namespace – using Configuation.Services;.

Next add the following codes inside the ConfigureServices() method:

services.AddSingleton<TotalUsers>();
services.AddMvc();

The services.AddSingleton(); will add the service which can now be shared all thought the application.

The services.AddMvc(); will add the necessary MVC services to the application. MVC actually needs a large number of services and the AddMvc() method sets up every service that MVC needs without the need of adding individual services, which MVC needs, one by one.

Next replace everything inside the Configure() method with – app.UseMvcWithDefaultRoute();. This makes the user of default routes. Don’t worry about it as you will learn about routes in the routes tutorial.

So the Startup class will now look like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Configuation.Services;

namespace Configuation
{
    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)
        {
            services.AddSingleton<TotalUsers>();
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMvcWithDefaultRoute();
        }
    }
}

Our service is now created and available through the application. Now I will show you how to use this service in a controller.

So create Controllers folder in the root of your application and add a new controller to it. Name this controller as ‘HomeController’. Import the namespace – using Configuation.Services; to the controller. Finally add the following code to it:

public class HomeController : Controller
{
    private TotalUsers totalUsers;
    public HomeController(TotalUsers tu)
    {
        totalUsers = tu;
    }

    public string Index()
    {
        return "Total Users are: " + totalUsers.TUsers();
    }
}

The controller has a constructor which has our service class (TotalUsers) in its parameter. When ASP.NET calls this controller it sees that the constructor requires an object of the service class (TotalUsers). MVC then goes to the Startup class and finds the TotalUsers class been configured as a service.

Therefore MVC will now create an instance of the TotalUsers class (by its own) and pass it to the construction of the Home Controller. This is the reason why I do not have to create the instance of the TotalUsers class in the Home Controller.

Now see the ‘Index’ action method of the controller, which uses the TotalUsers instance provided by MVC to the constructor, and calls the TUsers() method to get the total number of registered users, and finally returns them as string to the View.

To test the service run your application and see the total number of users displayed on the browser.

simple service in asp net core

Understanding Middleware in ASP.NET Core MVC

Middleware in ASP.NET Core are components that sits on the HTTP Request Pipeline and thus are used to configure them. There can be one or more Middlewares sitting on the HTTP pipeline in a line.

When a new HTTP request arrives, it is send to the first Middleware which inspects it. It will then do 1 of the 2 things:

1. Generate a response and send it back to the client (request initiator).
2. Pass the HTTP Request to the next Middleware.

On handling the request, the response will be returned to the client along the line, which allows all of the earlier Middleware to inspect or modify it.

There are 4 types of Middleware:

1. Content-Generating Middleware.
2. Short-Circuiting Middleware.
3. Request-Editing Middleware.
4. Response-Editing Middleware.

Content-Generating Middleware

Let us create a small Middleware that will only generate some content and hence named as Content-Generating Middleware.

Create a new folder inside the application’s root folder and name it ‘Middlewares’ (can be any name). Add a class to this new folder and name it ‘ContentMiddleware.cs’. Add its codes as shown below:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Configuation.Middlewares
{
    public class ContentMiddleware
    {
        private RequestDelegate nextDelegate;
        public ContentMiddleware(RequestDelegate next) => nextDelegate = next;

        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Path.ToString() == "/middleware")
            {
                await httpContext.Response.WriteAsync("This is from the content middleware");
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }
}

Please note that the Middleware class doesn’t implement an interface or derive from a common base class. They have a constructor that takes a parameter of type RequestDelegate which is provided to it automatically by MVC. The RequestDelegate object represents the next middleware component in the line.

The Middleware also define an Invoke method. This method is called when ASP.NET receives an HTTP request. The Invoke method has a parameter of type HttpContext which contains Information about the HTTP request and the response that will be returned to the client.

In my ‘ContentMiddleware.cs’ Class the Invoke method inspects the HTTP request and checks to see whether the request has been sent to the /middleware URL. If it has, then sends a simple text request ‘This is from the content middleware’ to the client. If a different URL has been initiated, then the request is forwarded to the next Middleware in the line.

Now you have to register the Middleware inside the Configure method of the Startup class using the UseMiddleware() method like shown below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    app.UseMiddleware<ContentMiddleware>();
}

Now run the application and then go to the URL – ‘/middleware’. You will see the response from the Middleware as shown below:

content middleware

If the URL is not – ‘/middleware’ then the ‘ContentMiddleware’ will pass the request to the next Middleware but here there is no Middleware left therefore the request is returned back.

content generating middleware

Using Services in Middleware

Middleware can also receive Services just like Controllers. In the previous section I created ‘TotalUsers’ service, you can use this service in your Middleware by providing the Service Class object, as a new parameter, in its constructor. See the below updated code:

using System.Threading.Tasks;
using Configuation.Services;
using Microsoft.AspNetCore.Http;

namespace Configuation.Middlewares
{
    public class ContentMiddleware
    {
        private RequestDelegate nextDelegate;
        private TotalUsers totalUsers;

        public ContentMiddleware(RequestDelegate next, TotalUsers tu)
        {
            nextDelegate = next;
            totalUsers = tu;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Path.ToString() == "/middleware")
            {
                await httpContext.Response.WriteAsync("This is from the content middleware, " + totalUsers.TUsers());
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }
}

Run you application and go to the URL – ‘/middleware’.

content middleware with service

Short-Circuiting Middleware

Short-Circuiting Middleware don’t always forward request to the next Middleware in the line. That’s why they are called Short-Circuiting Middleware.

Let’s create this type of Middleware. Inside the Middlewares’ folder create a new class and name it ‘ShortCircuitMiddleware’, and add the below code to it:

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Configuation.Middlewares
{
    public class ShortCircuitMiddleware
    {
        private RequestDelegate nextDelegate;
        public ShortCircuitMiddleware(RequestDelegate next) => nextDelegate = next;

        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Headers["User-Agent"].Any(v => v.Contains("Firefox")))            {
                httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }
}

Now go to the Configure method of the Startup class and register this middleware above the previous ‘ContentMiddleware’ Middleware, as shown below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<ShortCircuitMiddleware>();
    app.UseMiddleware<ContentMiddleware>();
    app.UseMvcWithDefaultRoute();
}

The Middleware executes in the order in which they are registered in the Configure method. I want ‘ShortCircuitMiddleware’ to execute before ‘ContentMiddleware’ so I have placed it before.

The ‘ShortCircuitMiddleware’ Middleware will not forward the request received from ‘Firefox’ browser, where it returns unauthorized status, for other browsers it forwards the request to the ‘ContentMiddleware’.

short circuiting middleware

If you now run your application and go to the URL – ‘/middleware’ then in Firefox browser you will receive a blank page. For other browsers you will get the same response which you get previously.

The blank page you get in Firefox browser is shown below:

blank page in firefox

Request-Editing Middleware

So far we have seen 2 types of Middleware that generates response. Now we will see Middleware that do not generate response but edits request. This type of Middleware is known as Request-Editing Middleware.

First create a class inside the Middleware folder and name it ‘RequestEditingMiddleware.cs’. Add the below code to it:

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Configuation.Middlewares
{
    public class RequestEditingMiddleware
    {
        private RequestDelegate nextDelegate;
        public RequestEditingMiddleware(RequestDelegate next) => nextDelegate = next;

        public async Task Invoke(HttpContext httpContext)
        {
            httpContext.Items["Firefox"] = httpContext.Request.Headers["User-Agent"].Any(v => v.Contains("Firefox"));
            await nextDelegate.Invoke(httpContext);
        }
    }
}

The RequestEditingMiddleware.cs Class only edits the HTTP Request (and does not sends any response). It checks if the request is made from Firefox browser in that case it adds a key ‘Firefox’ with Boolean value ‘true’ to the HttpContext dictionary.

Now you edit the ‘ShortCircuitMiddleware.cs’ class which we made earlier, so that the if condition (which is inside the invoke method) checks the ‘Firefox’ value in the HttpContext dictionary – if (httpContext.Items[“EdgeBrowser”] as bool? == true).

The updated code of ShortCircuitMiddleware.cs Class is given below:

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Configuation.Middlewares
{
    public class ShortCircuitMiddleware
    {
        private RequestDelegate nextDelegate;
        public ShortCircuitMiddleware(RequestDelegate next) => nextDelegate = next;

        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Headers["User-Agent"].Any(v => v.Contains("Firefox")))
            {
                httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }
}

Finally Register the Request Editing Middleware on the Configure method of Statup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<RequestEditingMiddleware>();
    app.UseMiddleware<ShortCircuitMiddleware>();
    app.UseMiddleware<ContentMiddleware>();
    app.UseMvcWithDefaultRoute();
}

I placed the Request-Editing Middleware at the start of the HTTP pipeline. This ensures that the request has already been modified before it is forwarded to other Middleware.

request editing middleware

Run the application in Firefox and go to the URL – ‘/middleware’. You will get a blank page due to unauthorized HTTP request condition given by the ‘Short-Circuiting Middleware’.

Response-Editing Middleware

As the name suggest the Response-Editing Middleware edits only the response generated by other Middleware.

On the Firefox browser we get a blank page. Now with the Response-Editing Middleware I will provide response which you will see on the browser.

Add a new Class inside the Middlewares folder and name it ‘ResponseEditingMiddleware.cs’. Add the below code to it:

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Configuation.Middlewares
{
    public class ResponseEditingMiddleware
    {
        private RequestDelegate nextDelegate;
        public ResponseEditingMiddleware(RequestDelegate next)
        {
            nextDelegate = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            await nextDelegate.Invoke(httpContext);
            if (httpContext.Response.StatusCode == 401)
            {
                await httpContext.Response.WriteAsync("Firefox browser not authorized");
            }
            else if (httpContext.Response.StatusCode == 404)
            {
                await httpContext.Response.WriteAsync("No Response Generated");
            }
        }
    }
}

In the above code if the http status code got in the response is 401 then I am adding text ‘Firefox browser not authorized’ to the response. Recall that the 401 un-authorized response is generated by ‘Short-Circuiting Middleware’.

Since the ‘Response-Editing Middleware’ only edits the response of other Middleware it has to be placed before other Middleware in the HTTP pipeline. So register it below other Middleware in the Configure method of Startup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<ResponseEditingMiddleware>();
    app.UseMiddleware<RequestEditingMiddleware>();
    app.UseMiddleware<ShortCircuitMiddleware>();
    app.UseMiddleware<ContentMiddleware>();
    app.UseMvcWithDefaultRoute();
}

response editing middleware

Now run your application and go to URL – ‘/middleware’ in the Firefox browser. You will get the response text – ‘Firefox browser not authorized’ on the browser as shown in the image below.

http response text in firefox-browser

When 404 Status Code is Received

In the Response-Editing Middleware you have an ‘else if’ code:

else if (httpContext.Response.StatusCode == 404)
{
    await httpContext.Response.WriteAsync("No Response Generated");
}

This will execute when no Middleware changes the response.

The Content Middleware is only component that is changing the response.

Just comment out the line that registers it on the Configure method – //app.UseMiddleware();. Then run your application and go to the URL – ‘/middleware’. You will see ‘No Response Generated’ message on your browser (other than Firefox).

no response generated

Understanding Application Builder

The Startup Class Configure() method has a parameter of type IApplicationBuilder Interface. This Interface allows the Middleware pipeline to be created just as what I did in the previous section.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //.....
}

An important use of IApplicationBuilder Interface is to configure the ASP.NET Core Routes. There are 2 important methods for doing routes configuration.

  • 1. UseMvcWithDefaultRoute
  • 2. UseMvc
UseMvcWithDefaultRoute

It is used to set up the default routes in the application. Use it inside the Configure method as shown below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...
    app.UseMvcWithDefaultRoute();
}

UseMvc

The UseMvc is used to configure custom routes in the application. Eg.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...
    app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
         });
}

The above code only shows one custom route. An application can have hundreds of routes set up.

The method UseMvcWithDefaultRoute is just a shortcut. When you use – app.UseMvcWithDefaultRoute(); you are just setting up the following route:

app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
         });

Understanding Hosting Environment

The Startup Class Configure() method has another parameter of type IHostingEnvironment Interface. It provides information about the hosting environment.

Let’s see some important properties of IHostingEnvironment Interface.

Name Description
ApplicationName Returns the name of the application.
EnvironmentName Returns the name of the environment.
ContentRootPath Returns the path that contains the application’s content & configuration files.
WebRootPath Returns the path that contains the application’s static content. This is usually wwwroot folder.
Using the Environment Name Property

In ASP.NET Core MVC there are 3 environments – Development, Staging & Production. Environments help in setting different configurations in the application.

To set up your environment in the application, go to the Solution Explorer and right click on your application name, on the list that appears select Properties.

In the properties page that Visual Studio opens for you, select the Debug option. There you will see the current hosting environment is set using an environment variable called ASPNETCORE_ENVIRONMENT. You can change its value to either Development, Staging & Production. When you are done save by pressing CTRL+S.

setting environment

Within the Configure method, you can determine which hosting environment is being used in the following manner:

  • IsDevelopment() – returns true if environment is Development.
  • IsStaging() – returns true if environment is Staging.
  • IsProduction() – returns true if environment is Production.

In the below code I made sure the Middleware are registered only if the environment is Production:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsProduction())
    {
        app.UseMiddleware<ResponseEditingMiddleware>();
        app.UseMiddleware<RequestEditingMiddleware>();
        app.UseMiddleware<ShortCircuitMiddleware>();
        app.UseMiddleware<ContentMiddleware>();
        app.UseMvcWithDefaultRoute();
    }
}

Using the WebRootPath Property to get the Absolute Path

The WebRootPath property gives the application’s static content folder which is the wwwroot. You can use this property inside a Controller to get the absolute path of the files kept in the static content folder.

To do this, pass the IHostingEnvironment as the parameter to the constructor of the Controller. The Dependency Injection feature of ASP.NET Core MVC will automatically provide the IHostingEnvironment value to the constructor. Then you can use the WebRootPath property to find the absolute path as shown below.

public class MediaController : Controller
{
    private IHostingEnvironment hostingEnvironment;

    public MediaController(IHostingEnvironment environment)
    {
        hostingEnvironment = environment;
    }

    public ActionResult Index()
    {
string absolutePath = Path.Combine(hostingEnvironment.WebRootPath, "file1.jpg"); 
return View();
    } 	
}

Enable Exception Handling

Exceptional Handling is not enabled in your application. You can check it by running your application and then go to some non-existing URL like ‘/Game’. You will see a message on the browser saying – ‘No Response Generated’.

no response generated for non existing url

This is an ‘Exception’ but the message does not state anything regarding the cause for this. User must see some proper message like 404 for non-existing page, 401 for un-authorized, 403 for forbidden. To do this you have to enable Exception Handling.

To enable Exception Handling in your application you need to put the below 2 lines of code inside the Configure() method:

app.UseDeveloperExceptionPage();
app.UseStatusCodePages();

  • UseDeveloperExceptionPage – displays the details of the Exception in the response.
  • UseStatusCodePages – adds descriptive messages to response like ‘404 – Not Found’

Now re-run your application and visit the URL – ‘/Game’. You will see the full exception details:

exception message on response

The above Exception was caused by the non-existing action method. In fact Exceptions can be cause by a number of ways, mainly due to wrong codes. I will show you what happens when exception occurs inside an action method code.

Go to the ‘Home Controller’ and add 2 action methods. The first is ‘Exception’ action that throws a NullReferenceException. The other is ‘Error’ action that will be automatically called when some exception happens in the code.

These 2 action methods are given below:

public ViewResult Exception()
{
    throw new System.NullReferenceException();
}

public ViewResult Error()
{
   return View();
}

Create an Error View inside ‘Views ➤ Home’ folder and add the following code to it:

<h2>Some Problem</h2>
We got some problem, please visit back after sometime.

Now re-run your application and visit the URL – ‘/Home/Exception’. You will see full Exception message with Stack Trace to explore the cause of the exception.

exception with stack trace

This full Exception message with Stack Trace is very helpful to developers but it should not be shown the common users of the site.

For this you use the method – IsDevelopment() to show full exception when website is running in Development mode (localhost).

When the website is running in production you show a common error view for exceptions.

Update your Configure method code with that shown below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseStatusCodePages();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMvcWithDefaultRoute();
}

The app.UseExceptionHandler(“/Home/Error”); method shows the Error View if the website is not running in the development mode.

Set the environment variable – ASPNETCORE_ENVIRONMENT to ‘Production’ and run the application and visit the ‘/Home/Exception’ page. You will see the ‘Error’ View as shown in the image below.

error view shown in exception

Enable Static Content

In order to make the application use images, JavaScript files, CSS stylesheets which are kept inside the wwwroot you have to add – app.UseStaticFiles(); inside the configure method.

I called the UseStaticFiles code for all environments since it is needed every time.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseMiddleware<ResponseEditingMiddleware>();
        app.UseMiddleware<RequestEditingMiddleware>();
        app.UseMiddleware<ShortCircuitMiddleware>();
        app.UseMiddleware<ContentMiddleware>();

        app.UseDeveloperExceptionPage();
        app.UseStatusCodePages();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

Understanding appsettings.json File

ASP.NET Core MVC has a JSON file by the name appsettings.json. In this file you can store any data like Connection String, logging settings, global variable, etc.

To create this file, right click the your project name in the Solution Explorer and select Add ➤ New Item. You will get ‘Add New Item’ dialog box opened up. In this dialog box, on the left side, select ‘Installed ➤ ASP.NET Core ➤ Web’. Then on the middle side, select ‘ASP.NET Configuration File’, and name the file ‘appsettings.json’. Finally click the ‘Add’ button to add this file to your application’s root folder.

The below figure shows how to select the ‘appsettings.json’ from the ‘Add New Item’ dialog box.

adding appsettings.json

In the appsettings.json file I want to store which middleware to enable in the application. So add the following code in your appsettings.json file:

{
  "Middleware": {
    "EnableContentMiddleware": true,
    "EnableShortCircuitMiddleware": true,
    "EnableRequestEditingMiddleware": true,
    "EnableResponseEditingMiddleware": false
  }
}

This JSON file contains 4 variables – EnableContentMiddleware, EnableShortCircuitMiddleware, EnableRequestEditingMiddleware & EnableResponseEditingMiddleware. I have given each of them a bool value, and I will read their values in Startup class, and based on the value I will register the Middleware if the value of the variable is true.

You can see the last variable – ‘EnableResponseEditingMiddleware’ is provided value as false and others variables are provided value as true. So all Middleware except the ‘Response Editing Middleware’ will be registered.

Now finally on your Startup file first add a property of type IConfiguration and add the constructor that takes the parameter of type IConfiguration. The parameter’s value will be provided automatically by ASP.NET Core from the Dependency Injection feature.

See the below code:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
public IConfiguration Configuration { get; } 

Finally change the code inside the Configure method as shown below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if ((Configuration.GetSection("Middleware")?.GetValue<bool>("EnableResponseEditingMiddleware")).Value)
    {
        app.UseMiddleware<ResponseEditingMiddleware>();
    }
    if ((Configuration.GetSection("Middleware")?.GetValue<bool>("EnableRequestEditingMiddleware")).Value)
    {
        app.UseMiddleware<RequestEditingMiddleware>();
    }
    if ((Configuration.GetSection("Middleware")?.GetValue<bool>("EnableShortCircuitMiddleware")).Value)
    {
        app.UseMiddleware<ShortCircuitMiddleware>();
    }
    if ((Configuration.GetSection("Middleware")?.GetValue<bool>("EnableContentMiddleware")).Value)
    {
        app.UseMiddleware<ContentMiddleware>();
    }
}

In the above code I am reading the bool value of these 4 variables which are kept inside the ‘Middleware’ node. If the value is true then the corresponding Middleware is registered.

When you run the application, all except the ‘Response Editing Middleware’ will be registered.

Selecting Different appsettings.json files based on different Environment

As stated earlier the appsettings.json stores the connection string for the database. During the course of application development the programmers will want to have not 1 but 2 appsetting.json files in their application.

One that will be used during development and which will contains the connection string (or other variables) to local database.

The other one will be used during production (i.e. when you publish the website and put it on hosting server), and this one will contain the connection string to the production database i.e. the live database.

I will show you how to do this.

First add your connection string to your live database on your appsettings.json file like shown below:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=SQL6003.site4now.net;Database=DB_A3CE39_y11;User Id=DB_PCE39_y11_admin;[email protected];"
  }
}

Now add a new appsetting.json file on your application root folder and give it the name – appsettings.development.json. Then add your local development database connection string as shown below.

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=vaio;Database=Goldentaurus;Trusted_Connection=True;"
  }
}

This newly added appsettings.development.json file will remain hidden in the solutions explorer. To view this file right click the arrow (➤) before the span class=”term”>appsettings.json file.

The below image explains this:

seeing hidden appsettings.development.json

Now go to the Program.cs file and change the BuildWebHost method from:

public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();

To:

public static IWebHost BuildWebHost(string[] args)
{
    return new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        var env = hostingContext.HostingEnvironment;
        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    })
    .UseIISIntegration()
    .UseStartup<Startup>()
    .Build();
}

Inside this method you will see a method ConfigureAppConfiguration() being called. It is used to register the appsettings.development.json file.

Now you can run your application and will find the appsettings.development.json file is used when the application runs in development (localhost), and the other appsettings.json file is used in production (live) environment.

To get the connection string, add to the ConfigureServices method of the Starup class, the following code:

services.AddDbContext<SomeClass>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));

This code will provide the constructor of ‘SomeClass.cs’ this Connection string value.

You can download the full codes of this tutorial from the below link:

Download

Conclusion

I hope you understood how to do configurations in your application one-by-one. It is really important to understand the working of ASP.NET Core MVC and I hope this tutorial has done justice to it.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.