Exception handling in Asp.net Core 2.2/3.0(Part 6)


Exception handling is one of the common practice in any web application development. In all web technology we will do it different ways like in asp.net web form we were doing using global.aspx file, while in asp.net mvc we were doing using [HandleError] attribute.

But in asp.net mvc core there is separate way to handle the exception handling i.e. using exception handling middleware like app.UseDeveloperExceptionPage(); and app.UseExceptionHandler

If we will create any asp.net mvc core application by default this middleware will be present.

app.UseDeveloperExceptionPage(): It is used for displaying the user friendly exception on development environment. This will work as global exception handling. It is one of the cool feature of asp.net core.

Just to reproduce the exception i have written the code in HomeController like this

Now if we will run the application on Development Env, we will get the exception like this.

In the above screen shot we are getting the clear error message to fix the issue. This is very useful for developer to quickly fix the issue without debugging the application.

If the application has been deployed to Prod then we will get the custom error message like this
app.UseExceptionHandler(“/Home/Error”);

If we have to display the StatusCode of Error message then we can use this middleware like this

Now if we will run the code in Development and Prod Env we will get output like this

In the above image we are getting the status code 500. This method will display the status codes between 400 and 599 that do not have a body.

This is the magic of Middleware which is making our life easier to be more productive.

Advertisement

Branching in the MiddleWare of Asp.net Core (Part 5)


In the previous example there was only one branch in the middleware. The middleware flow will always come from A to B. There will not be always the same scenario. We can also divert the flow of middleware on basis of input request.

There could be two type branches: branches that rejoin the main pipeline, and branches that don’t

Example of non-rejoining branch in middleware

This can be done using the Map or MapWhen method. Map is used for specifying a branch based on the request path. MapWhen gives us more control on the input request. We can specify a predicate on the HttpContext to decide whether to branch or not.

Here is the demo code for this example

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;

namespace MiddleWare_Sample
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        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)
        {

            //Middleware A
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("A (before)");
                await next();
                Debug.WriteLine("A (after)");
            });

            app.Map(
                new PathString("/emp"),
                a => a.Use(async (context, next) =>
                {
                    Debug.WriteLine("B (before)");
                    await next();
                    Debug.WriteLine("B (after)");
               }));

            app.Run(async context =>
            {
                Debug.WriteLine("C");
                await context.Response.WriteAsync("Hello world");
            });
        }
    }
}

In the above code, if the browser URL will be https://localhost:44338/ then middleware flow will be

if the URL will be https://localhost:44338/emp then flow will be like this

in the above request response will be 404 (Not found). This is because the B middleware calls next(), but there’s no next middleware, so it falls back to returning a 404 response. To solve this, we could use Run instead of Use, or just not call next().

Example of Rejoining branch in middleware

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;

namespace MiddleWare_Sample
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        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)
        {

            //Middleware A
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("A (before)");
                await next();
                Debug.WriteLine("A (after)");
            });

            app.UseWhen(
                context => context.Request.Path.StartsWithSegments(new PathString("/emp")),
                a => a.Use(async (context, next) =>
                {
                    Debug.WriteLine("B (before)");
                    await next();
                    Debug.WriteLine("B (after)");
               }));

            app.Run(async context =>
            {
                Debug.WriteLine("C");
                await context.Response.WriteAsync("Hello world");
            });
        }
    }
}

If we run the above code, if the path will be https://localhost:44338 then output will be

If the path will be https://localhost:44338/emp then out put will be like this

This is the complete example of middleware with demo. I hope it will be useful to understand the concept of middleware.

Short-Circuiting Demo in Middleware of Asp.net core (Part 4)


As the name suggesting short-circuiting means breaking the flow of execution before the destination in middleware.

As shown in the above example, if we have to break the follow of execution in middleware we have implement the short-circuiting functionality. We can do it by just removing the next() method in the middleware.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;

namespace MiddleWare_Sample
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        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)
        {

            //Middleware A
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("A (before)");
                await next();
                Debug.WriteLine("A (after)");
            });

            // Middleware B
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("B (before)");
                //await next();
                await context.Response.WriteAsync("This is the end of execution of middleware B");
                Debug.WriteLine("B (after)");
            });

            // Middleware C (terminal)
            app.Run(async context =>
            {
                Debug.WriteLine("C (end MiddleWare in pipeline)");
                await context.Response.WriteAsync("Hello world");
            });
        }
    }
}

Output:

As shown in the above code, after commenting on next() method, middleware end terminal is not executing. It is breaking the flow before the end terminal. If we will get scenario to short-circuiting in middleware we can achieve like this.

Middleware in asp.net core 2.2 (Part 3)


As the name suggest middleware means it will work as mediator between request and response. It is pieces of code that handle the requests and responses. They also chained each other to form the pipeline. Any incoming request are passed through the pipeline where each middleware has a chance to do some task before passing to next middleware in the pipeline

Outgoing response also passed through the same pipeline in reversed order as given below image.

Middleware can do all type of task like handling authentication, errors, static files, MVC etc. in ASP.NET Core.

1. In middleware request can pass from all middleware in pipeline.
2. There could be also Short-circuiting in middleware.
3. There could be also Branching the pipeline in middleware
4. There could be also Rejoining of branch in middleware.
5. There could be also Non-Rejoining of branch in middleware.

How to configure pipeline
We typically configure the asp.net pipeline in the Configure method of Startup class by calling Use* methods on the IApplicationBuilder. As given below image

In the above image, we saw that each use* method is using to add the middleware in pipeline. In the above example Request will pass through DeveloperExceptionPage –> StaticsFiles –> Authentication
–> MVCWithDefaultRoute

Again response will pass through MVCWithDefaultRoute–> Authentication–> StaticsFiles
–> DeveloperExceptionPage middleware.

Use and Run are the extension method to add the middleware to the pipeline. Run is used to add a terminal middleware which will execute at last of the pipeline.

Now we will see the basic example of request and response flow where request will pass from start middleware to end terminal middleware and response will pass from end terminal middleware to Start middleware.

Basis Pipeline Example

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;

namespace MiddleWare_Sample
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        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)
        {

            //Middleware A
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("A (before)");
                await next();
                Debug.WriteLine("A (after)");
            });

            // Middleware B
            app.Use(async (context, next) =>
            {
                Debug.WriteLine("B (before)");
                await next();
                Debug.WriteLine("B (after)");
            });

            // Middleware C (terminal)
            app.Run(async context =>
            {
                Debug.WriteLine("C (end MiddleWare in pipeline)");
                await context.Response.WriteAsync("Hello world");
            });

        }
    }
}

In the above example we saw the basic middleware without any condition. But we can design the middleware on basis of our requirement. In next post i will share the remaining the middleware with example. Thanks for reading.

Dependency Injection in Asp.net Core 2.2 (Part 2)


ASP.NET Core is designed from scratch to support Dependency Injection. DI will help the application to create test driven and loosely couple application. This is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.

what are the advantages of Dependency Injection ?
1.Better unit testing.
2. Clean and easy to understand Code
3.better re-usability of code.
4. Loose Coupling application
5. concreate class can be replaced by Mocks

ASP.NET Core framework has simple inbuilt IoC container which does not have as many features as other third party IoC containers like StructureMap, Unity, Ninject etc. For more details please look on below old post

https://chandradev819.wordpress.com/2019/03/24/how-to-implement-structure-map-in-asp-net-mvc-application/

https://chandradev819.wordpress.com/2018/06/05/how-to-implement-the-dependency-injection-in-asp-net-mvc/

If you want more features such as auto-registration, scanning, interceptors, or decorators then you may replace built-in IoC container with a third party container.

What is the IOC Container ?

>> It is the factory class which take care of creation of all object in the system and injecting the right dependencies. It is also called as container.

The container, called an Inversion of Control (IoC) container, keeps a list of all the interfaces needed and the concrete class that implements them. When asked for an instance of any class, it looks at the dependencies it needs and passes them based on the list it keeps. This way very complex graphs of objects can be easily created with a few lines of code.

In addition to managing dependencies, these IoC containers also manage the lifetime of the objects they create. They know whether they can reuse an instance or need to create a new one.

How to Configuring dependency injection in ASP.NET Core ?

We can configure the dependency injection in ConfigureServices method.

public void ConfigureServices(IServiceCollection services) 
{   
// Here goes the configuration
}

In the above method it will accept as type IServiceCollection. This is the list used by the container to keep track of all the dependencies needed by the application. So we have to register the required services in the above methods.

There are two types of dependencies that can be added to the services list.

1.Framework Services: Services which are a part of ASP.NET Core framework.They are usually configured using extension methods like AddServiceName

For example, if you want to use ASP.NET Core MVC, you need to write services.AddMvc() so that all the controllers and filters are automatically added to the list. Also, if you want to use Entity Framework, you need to add DBContext with services.AddDbContext(…).

2. Application Services: The services (custom types or classes or Interface) which you as a programmer create for your application.

Since we are adding them by our-self, we have to also specify the lifetime of service.

There are 3 type of Lifetime of Service

1. Transient : This lifecycle is used for lightweight services that do not hold any state and are fast to instantiate. They are added using the method services.AddTransient(), and a new instance of the class is created every time it is needed.

2. Scoped: This is typically used for services that contain a state that is valid only for the current request, like repositories and data access classes.

Services registered as scoped will be created at the beginning of the request, and the same instance will be reused every time the class is needed within the same request. They are added using the method services.AddScoped().

3. Singleton : IoC container will create and share a single instance of a service throughout the application’s lifetime. Such services typically hold an application state like an in-memory cache. They are added via the method services.AddSingleton().

Demo sample for using dependency injection in asp.net core

Step 1: Create the interface of Service in Service folder of application like this



using System;

namespace HelloWorld_Demo.Service
{
    public interface IClock
    {
        DateTime GetTime();
    }
}

Step 2: Create the implementation of interface like this in Clock class

using System;

namespace HelloWorld_Demo.Service
{
    public class Clock : IClock
    {
        public DateTime GetTime()
        {
            return DateTime.Now;
        }
    }
}

Step 3: Create the blank HomeController in Controllers Folder and implement the constructor injection like this

using HelloWorld_Demo.Service;
using Microsoft.AspNetCore.Mvc;

namespace HelloWorld_Demo.Controllers
{
    public class HomeController : Controller
    {
        private readonly IClock _clock;

        public HomeController(IClock clock)
        {
            _clock = clock;
        }

        public IActionResult Index()
        {
            ViewData["Message"] = $"It is {_clock.GetTime().ToString("T")}";
            return View();
        }
    }
}

Step 4: Create the html view like this

 = "Index";
}

<h3>Demo sample of Dependency Injection in asp.net core MVC</h3>

<p>@ViewData["Message"]</p>

Step 5: Go to the Startup.cs file and Add the Framework service i.e. MVC and Application Service which one we have created IClock as given below


using HelloWorld_Demo.Service;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace HelloWorld_Demo
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //Added the Framework Service to use MVC functiionality
            services.AddMvc();

            //Added application services
            services.AddTransient<IClock, Clock>();
        }

        // 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();
            }
            if (env.IsProduction())
            {

            }
            //app.Run(async (context) =>
            //{
            //    await context.Response.WriteAsync("Hello World!");
            //});
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Step 6: Run the application