ASP.NET Core

Custom Middleware in ASP.NET Core

Custom Middleware in ASP.NET Core

Custom Middleware in ASP.NET Core

We can also build our own Custom Middleware in ASP.NET Core. The custom middleware can be either of 4 types: -
1. Content-Generating Middleware - The Content-Generating Middleware generates some content or Response and return Response to the client
2. Short-Circuiting Middleware - Prevents further middleware from processing the request because it short-circuits the pipeline.
3. Request-Editing Middleware - Use to edits http requests, instead of generating response
4. Response-Editing Middleware - User to Edits the response generated by other Middleware.


Each Middleware must have 2 things:

1. A RequestDelegate (Microsoft.AspNetCore.Http) object,
   which is used to process the http requests. The RequestDelegate represents the next middleware component in the http pipeline and is injected to the controller of Middleware with Dependency Injection.
2. An Invoke method
   which is called whenver the Middleware is called or .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.


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.


Content-Generating Middleware -
Step 1: Create Class for custom middleware

namespace Practice.Middlewares
{
    public class ContentMiddleware
    {
        private RequestDelegate nextDelegate;
        public ContentMiddleware(RequestDelegate next) => nextDelegate = next;
 
// Invoke method inspects the HTTP request and checks to see whether the request has been sent to the url /middleware.
// If it has, then it sends a simple text response
        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Path.ToString() == "/middleware") {
                await httpContext.Response.WriteAsync("This is from the custom content middleware");
            }
            else {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }
}

Step 2: Register the Middleware inside the Program.cs class using the UseMiddleware() method

using Practice.Middlewares;
using Practice.Services;
 
var builder = WebApplication.CreateBuilder(args);
 
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<TotalUsers>();
var app = builder.Build();
 
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days.
    app.UseHsts();
}
 
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseMiddleware<ContentMiddleware>();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
 
app.Run();

Step 3: Check: Run the application and then go to the URL – https://localhost:44343/middleware. You will see the response from the Middleware





Inject services to Middleware with dependency injection
We can inject services to Middleware with dependency injection, by injecting that service in the constructor of the middleware.

public class ContentMiddleware
{
    private RequestDelegate nextDelegate;
    private TotalUsers totalVisitors;

    public ContentMiddleware(RequestDelegate next, TotalVisitors tv)
    {
        nextDelegate = next;
        totalVisitors = tv;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        if (httpContext.Request.Path.ToString() == "/middleware") {
            await httpContext.Response.WriteAsync("Total Visitors: " + totalVisitors.Visitors());
        }
        else {
            await nextDelegate.Invoke(httpContext);
        }
    }
}




Short-Circuiting Middleware -
Step 1: Create Class for custom middleware
The Short-Circuit Middleware checks the User-Agent in the header to find out if the browser is firefox. In that case it does not forward the request and returns unauthorized status.

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);
        }
    }
}


// Register Middleware
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();
       
        app.UseMiddleware<ShortCircuitMiddleware>();
        app.UseMiddleware<ContentMiddleware>();

        app.Run();
    }
}

Step 2: If you now run your application and open the URL – https://localhost:7164/middleware in Firefox browser. You will receive a blank page. Whereas in other browsers you will get the response from The ContentMiddleware




Request-Editing Middleware -
Step 1: Create Class for custom middleware and do some changes in RequestEditingMiddleware

public class RequestEditingMiddleware
{
    private RequestDelegate nextDelegate;
    public RequestEditingMiddleware(RequestDelegate next) => nextDelegate = next;

    public async Task Invoke(HttpContext httpContext)
    {            
        // Add a Key with Boolean value ‘true’ to the HttpContext dictionary, in case request is coming from firefox browser
        httpContext.Items["Firefox"] = httpContext.Request.Headers["User-Agent"].Any(v => v.Contains("Firefox"));
        await nextDelegate.Invoke(httpContext);
    }
}

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")))
        if (httpContext.Items["Firefox"] as bool? == true)
        {
            httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
        }
        else
        {
            await nextDelegate.Invoke(httpContext);
        }
    }
}

// Register our new Middleware at the top
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.UseMiddleware<RequestEditingMiddleware>();
        app.UseMiddleware<ShortCircuitMiddleware>();
        app.UseMiddleware<ContentMiddleware>();

        app.Run();
    }
}

Step 2: Run the application and upon the URL – https://localhost:7164/middleware in firefox. You will get the same blank page due to unauthorized HTTP request condition.




ShortCircuitMiddleware
Step 1: Create Class for custom middleware and do some changes in ShortCircuitMiddleware

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");
        }
    }
}

// Register our new Middleware at the top
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();
             
        app.UseMiddleware<ResponseEditingMiddleware>();
        app.UseMiddleware<RequestEditingMiddleware>();
        app.UseMiddleware<ShortCircuitMiddleware>();
        app.UseMiddleware<ContentMiddleware>();

        app.Run();
    }
}

Step 2: Run the application and upon the URL – https://localhost:7164/middleware in firefox. You will get the same blank page due to unauthorized HTTP request condition.
if the HTTP status code in the response is 401 (as we set earlier in our Short-Circuiting Middleware), show text on browser 'Firefox browser not authorized', for other browser it show content from ContentMiddleware


Try to Browser a wrong URL https://localhost:7164/middleware1, you will get anothe message



Register Middleware Using Extention Method
We Register Middleware Using Extension method






Related Post

About Us

Community of IT Professionals

A Complete IT knowledgebase for any kind of Software Language, Development, Programming, Coding, Designing, Networking, Hardware and Digital Marketing.

Instagram