Click here to Skip to main content
15,921,371 members
Articles / Web Development / ASP.NET / ASP.NET Core

ASP.NET Core 2.0 Middleware

Rate me:
Please Sign up or sign in to vote.
1.80/5 (3 votes)
6 Sep 2017CPOL2 min read 7.7K   1  
Create a Hello World using ASP.NET Core Middleware. Continue reading...

Problem

Create a Hello World using ASP.NET Core Middleware.

Solution

Starting from the Empty Project from a previous post, amend the Configure() method in Startup.cs as below:

C#
public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            // setup request pipeline using middleware
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World! (Run)");
            });
        }

It is a good practice to use extension methods on IApplicationBuilder to build the pipeline:

C#
// RunMiddlewareExtensions.cs
        public static void RunHelloWorld(this IApplicationBuilder app)
        {
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World! (Run)");
            });
        }
        // Startup.cs
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            // setup request pipeline using middleware
            app.RunHelloWorld();
        }

In the previous snippet, we used IApplicationBuilder.Run() to configure middleware, another way to do this is IApplicationBuilder.Use():

C#
// UseMiddlewareExtensions.cs
        public static IApplicationBuilder UseHelloWorld(
            this IApplicationBuilder app)
        {
            return app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("Hello World! (Use)\n");
                await next();
            });
        }
        // Startup.cs
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            // setup request pipeline using middleware
            app.UseHelloWorld();
            app.RunHelloWorld();
        }

It is a good practice to have middleware components defined in a separate class:

C#
public class HelloWorldMiddleware
    {
        private readonly RequestDelegate next;

        public HelloWorldMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            await context.Response.WriteAsync("Hello World! (Use in Class)\n");
            await this.next(context);
        }
    }
    // UseMiddlewareExtensions.cs
    public static IApplicationBuilder UseHelloWorldInClass(
       this IApplicationBuilder app)
    {
    	  return app.UseMiddleware<HelloWorldMiddleware>();
    }
    // Startup.cs
    public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
    {
        // setup request pipeline using middleware
        app.UseHelloWorld();
        app.UseHelloWorldInClass();
        app.RunHelloWorld();
    }

Discussion

Middleware is a component that intercepts HTTP request and response messages. We create a chain of these components to build a request pipeline for our application.

We setup this pipeline in Configure() method via its IApplicationBuilder parameter, that has the following methods for this purpose:

  1. Run(): Adds a middleware and ends the pipeline, i.e., doesn’t call next middleware
  2. Use(): Adds a middleware, as a lambda or a dedicated class
  3. Map(): Adds middleware based on request paths

Run

It takes RequestDelegate delegate as a parameter, which when called has HttpContext as its parameter. It returns void because it short-circuits the request pipeline.

Use

It takes Func as a parameter, i.e., takes in HttpContext and a pointer to next middleware, and returns nothing (Task). If the next middleware is not called, it short-circuits the request pipeline (same as Run).

UseMiddleware

When setting up middleware as a class, we use UseMiddleware to wire it up, providing our class as generic parameter.

The dedicated middleware class has two important pieces in it:

  1. Its constructor accepts RequestDelegate. This will be called to forward the request to next middleware.
  2. It has a method Invoke accepting HttpContext and returning a Task. This is called by the framework when calling the middleware.

Note: Implementing middleware in a dedicated class and wiring up using UseMiddleware is the best/cleanest approach.

Extension Methods

Note the difference in extension methods, RunXXX doesn’t return a value I however UseXXX does (IApplicationBuilder). This is because Run() ends (short-circuits) the pipeline whereas Use() may be chained with other middleware.

Order

Middleware components are called in the order they appear in Configure() method, i.e., the order in which they are added to the pipeline. The response, on its way back to the client, also passes through the same middleware pipeline.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
-- There are no messages in this forum --