ASP.NET Core - Custom Middleware

Introduction

In this article, we are going to discuss Custom Middleware. This is a second article on middleware. I recommend reading the first article here before continuing on this.

This article can be used by beginners, intermediates, and professionals.

We are going to cover,

  1. How to create custom Middleware?
  2. How to use custom middleware in the HTTP pipeline?

Let’s start with custom Middleware,

How to create custom Middleware?

Asp.net core provided many in-build Middleware but in some scenarios, we need our own middleware to fulfill our requirement, in such case will go with custom middleware.

In the first article, we have written inline middleware but in the real world, we will create a separate class for middleware that is called custom middleware. 

There are 2 ways to create Custom Middleware in Asp.net Core.

  1. Using IMiddleware interface
  2. Using the extension method.

Let’s try to learn how to create custom middleware using IMiddelware Interface the below example,

Step 1

Create a class and name it “CustomeMiddlewareDemo

namespace WebApplication1 {
    public class CustomMiddlewareDemo {}
}

Step 2

Inherit “IMiddleware” interface from “Microsoft.AspNetCore.Http” namespace and implement it as per the below code.

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace WebApplication1 {
    public class CustomMiddlewareDemo: IMiddleware {
        public Task InvokeAsync(HttpContext context, RequestDelegate next) {
            throw new System.NotImplementedException();
        }
    }
}

Step 3

Now we will add code for Custom middleware in the “InvokeAsync” method.

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace WebApplication1 {
    public class CustomMiddlewareDemo: IMiddleware {
        public async Task InvokeAsync(HttpContext context, RequestDelegate next) {
            await context.Response.WriteAsync("Hellow from Custom Middleware");
            await next(context);
        }
    }
}

You might notice that I have added async and await for “InvokeAsync” Method.

We have created a separate file for Custom Middleware and now we will learn how to use it.

How to use Middleware in the HTTP Pipeline?

We will consume newly created custom middleware in the HHTP pipeline.

As we know if want to use any kind of new services in the ASP.Net Core application then before we use we need to register startup.cs -> “ConfigureServices” method.

Before we use Custom middleware in the code, we will register in the “Configure Service” method.

Step 4

Configure CustomMiddleware in the “ConfigureService” Method.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1 {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
        public IConfiguration Configuration {
            get;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddControllersWithViews();
            services.AddTransient < CustomMiddlewareDemo > ();
        }
        // 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();
            } else {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => {
                endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Step 5

Now we will use CustomMiddleware in the HTTP Pipeline. For that, we will inject custom Middleware in the “Configure” method like below.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1 {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
        public IConfiguration Configuration {
            get;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddControllersWithViews();
            services.AddTransient < CustomMiddlewareDemo > ();
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            app.UseMiddleware < CustomMiddlewareDemo > ();
            app.Run(async context => await context.Response.WriteAsync("Hello"));
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            } else {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => {
                endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

OUTPUT

Now we will create custom middleware using the extension method,

Step 1 - Add a new Middleware class to the project

Right Click on Project -> Add -> new item -> Asp.net Core -> Middleware class

Click on Add button and observed Middleware class code.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace WebApplication1 {
    // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class MyMiddleware {
        private readonly RequestDelegate _next;
        public MyMiddleware(RequestDelegate next) {
            _next = next;
        }
        public Task Invoke(HttpContext httpContext) {
            return _next(httpContext);
        }
    }
    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class MyMiddlewareExtensions {
        public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder) {
            return builder.UseMiddleware < MyMiddleware > ();
        }
    }
}

Step 2

Add your custom code in the “Invoke” method of the Middleware class.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace WebApplication1 {
    // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class MyMiddleware {
        private readonly RequestDelegate _next;
        public MyMiddleware(RequestDelegate next) {
            _next = next;
        }
        public async Task Invoke(HttpContext httpContext) {
            await httpContext.Response.WriteAsync("Hellow Custom Middleware \n");
            await _next(httpContext);
        }
    }
    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class MyMiddlewareExtensions {
        public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder) {
            return builder.UseMiddleware < MyMiddleware > ();
        }
    }
}

Step 3

Use Custom Middleware in the HTTP pipeline.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1 {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
        public IConfiguration Configuration {
            get;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddControllersWithViews();
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            app.UseMyMiddleware();
            app.Run(async context => await context.Response.WriteAsync("Hello"));
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            } else {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => {
                endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

OUTPUT

That’s all for this article. Hope you enjoyed and learn how to create and configure Custom Middleware in the HTTP Pipeline.