Select Page

ASP.NET Core Middleware

by | May 3, 2020 | Programming | 0 comments

Middleware got introduced in ASP.NET with .NET Core. ASP.NET Core Middleware allows controlling the web application request pipeline. The middleware approach got introduced to configure the ASP.NET request pipeline.

Introduction

ASP.NET Core Middleware is a piece of code that gets executed on every request. ASP.NET Core comes with built-in middleware e.g. routing, session, MVC, etc and one can write their own custom middleware as well. Middleware forms an application pipeline to handle requests & responses and a pipeline consists of a series of middleware that gets executed in the configured order.

Request pipeline can be a combination of built-in Middleware, third party middleware, or your own custom middleware like logging middleware, exception middleware, etc.

Middleware can be directly added using request delegates that handle each HTTP request. Request delegates can be configured using Run, Use & Map methods directly in the startup.cs file in Configure Method. Alternatively, middleware can also be configured using a separate reusable class.

Based on the request type, each Middleware can decide whether to perform work on request (before & after the next component in a pipeline), do nothing, and forward the request to the next middleware or short circuit the pipeline by generating a response. When middleware short circuits pipeline its called terminal middleware.

ASP.NET Core Middleware

Implement ASP.NET Core Middleware

ASP.NET Core Middleware can be implemented using request delegates – Run, Use, Map in the startup.cs file and also by implementing custom middleware class. Both methods have been covered below.

Create a middleware with IApplicationBuilder – Run, Use and Map

Configure the HTTP pipeline using Run, Use, and Map request delegates. Request delegates can be registered as in-line anonymous methods through startup.cs in Configure Method. ASP.NET Core Request Delegates – Run, Use & Map can be used to alter request pipeline.

Run – Generates a response and terminates the pipeline i.e. no other middleware will run after this. Typically should be placed at the end of the pipeline. When a request is not passed to next delegate its called short-circuiting the request pipeline (i.e. terminal middleware)

public class Startup { public void Configure(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync(“Hello, Some Response Text!!”); }); } }

Use – Connects multiple middlewares in a pipeline. Performs tasks before and after the next delegate. Parameter next will take to next middleware in the pipeline. Conditionally you can even short-circuit the pipeline by not calling the next parameter.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Code Logic that does not short cicuits pipeline
            await next.Invoke();
            // Code Logic
        });
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Some Response From next delegate in pipeline!!");
        });
    }
}

Don’t call next.Invoke() after the response has been sent to the client as any changes to the response after the response has started will result in an exception.

Map – Maps are used to reroute the request to different middleware components based on incoming requests. Map and MapWhen reroute the request pipeline based on matches of the specified request path.

public class Startup
{
    private static void HandleContact(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Contact us at [email protected]");
        });
    }
    
    private static void HandleAbout(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hi from rsmrocks");
        });
    }
    
    private static void HandleWelcome(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Welcome to our Blog");
        });
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.Map("/contact", HandleContact);
        app.Map("/about", HandleAbout);
        app.MapWhen(context => context.Request.Query.ContainsKey("welcome"), HandleWelcome);
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from delegate without Map!");
        });
    }
}

Newsletter Subscription

Stay updated! Instantly get notified about my new articles in your mailbox by subscribing via email

Create a middleware using custom middleware

Request Delegates inside startup.cs will be difficult to maintain when request pipeline complexity increases. We generally want to keep code clean and also allow middleware to handle single responsibility so middleware is implemented as standalone reusable classes. Middleware class is a class with an invoke method that contains code logic and also has a constructor that accepts a RequestDelegate.

public class MyFirstMiddleware
{
    private readonly RequestDelegate _next;
    public MyFirstMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    
    public async Task Invoke(HttpContext httpContext)
    {
        // Code Logic before next middleware
        await _next(httpContext);
        // Code Logic after next middleware
    }
}

We can directly use the above middleware class in a startup.cs but to keep it clean we can add below extension class which uses IApplicationBuilder and then use this extension in configure method in startup.cs

public static class MyFirstMiddlewareExtensions
{
    public static IApplicationBuilder UseMyFirstMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware();
    }
}

Now our configure method in startup class will look like this

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

Middleware Order

ASP.NET Core request processing pipeline consists of a series of middleware that handles the request/response one by one i.e. they are called one by one by .NET core framework. The sequence in which these middlewares are configured is called Middleware Order.

The order in which ASP.NET Core Middleware Components are added in the Configure method of the Startup class method defines the order in which middleware components are invoked for handling request as well as response.

Summary

  • ASP.NET Core Middleware is a piece of code that gets executed on every request
  • Request pipeline can be a combination of built-in Middleware, third party middleware or your own custom middleware like logging middleware, exception middleware, etc.
  • Middleware can be directly added using request delegates like Run, Use & Map in the startup.cs file in Configure Method. Alternatively, middleware can also be configured using a separate reusable class.

You can also check my another Article explaining how to analyze ASP.NET application issues – https://procodeguide.com/programming/analyze-aspnet-application-issues/

References: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0#use-run-and-map

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2

Hope you found this article useful
Buy me a coffeeBuy me a coffee

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Credit card sized computer, Home Automation and much more with Raspberry Pi 4

Improve performance of your laptop by replacing hdd with ssd