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.

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.