Fundamentals On Middleware

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 9
At a glance
Powered by AI
Middleware is a component that is executed on every request in ASP.NET Core and builds the request pipeline. Middleware can be either framework provided, added via NuGet, or custom middleware. The order of middleware execution can be configured.

Middleware is similar to handlers and modules from classic ASP.NET. Middleware gets executed sequentially and each middleware can optionally call the next middleware. Middleware is configured using extension methods on IApplicationBuilder like Use, Run, etc.

Multiple middleware can be configured by calling Use or Run extension methods sequentially on IApplicationBuilder. The order of calls determines the order of execution.

ASP.

NET Core - Middleware


ASP.NET Core introduced a new concept called Middleware. A middleware is nothing but a
component (class) which is executed on every request in ASP.NET Core application. In the
classic ASP.NET, HttpHandlers and HttpModules were part of request pipeline. Middleware is
similar to HttpHandlers and HttpModules where both needs to be configured and executed in
each request.

Typically, there will be multiple middleware in ASP.NET Core web application. It can be either
framework provided middleware, added via NuGet or your own custom middleware. We can set
the order of middleware execution in the request pipeline. Each middleware adds or modifies
http request and optionally passes control to the next middleware component. The following
figure illustrates the execution of middleware components.

AS
P.NET Core Middleware

Middlewares build the request pipeline. The following figure illustrates the ASP.NET Core
request processing.

ASP.NET Core Request Processing

Configure Middleware
We can configure middleware in the Configure method of the Startup class using
IApplicationBuilder instance. The following example adds a single middleware using Run
method which returns a string "Hello World!" on each request.

public class Startup


{
public Startup()
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
//configure middleware using IApplicationBuilder here..

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World!");

});

// other code removed for clarity..


}
}

In the above example, Run() is an extension method on IApplicationBuilder instance which


adds a terminal middleware to the application's request pipeline. The above configured
middleware returns a response with a string "Hello World!" for each request.

Understand Run Method


We used Run extension method to add middleware. The following is the signature of the Run
method:

Method Signature:
public static void Run(this IApplicationBuilder app, RequestDelegate handler)

The Run method is an extension method on IApplicationBuilder and accepts a parameter of


RequestDelegate. The RequestDelegate is a delegate method which handles the request. The
following is a RequestDelegate signature.

Method Signature:
public delegate Task RequestDelegate(HttpContext context);

As you can see above, the Run method accepts a method as a parameter whose signature should
match with RequestDelegate. Therefore, the method should accept the HttpContext parameter
and return Task. So, you can either specify a lambda expression or specify a function in the Run
method. The lambda expression specified in the Run method above is similar to the one in the
example shown below.

public class Startup


{
public Startup()
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(MyMiddleware);
}

private Task MyMiddleware(HttpContext context)


{
return context.Response.WriteAsync("Hello World! ");
}
}

The above MyMiddleware function is not asynchronous and so will block the thread till the time
it completes the execution. So, make it asynchronous by using async and await to improve
performance and scalability.

// other code removed for clarity

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.Run(MyMiddleware);
}

private async Task MyMiddleware(HttpContext context)


{
await context.Response.WriteAsync("Hello World! ");
}

Thus, the above code snippet is same as the one below.

app.Run(async context => await context.Response.WriteAsync("Hello World!") );

//or

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World!");
});

So, in this way, we can configure middleware using Run method.

Configure Multiple Middleware


Mostly there will be multiple middleware components in ASP.NET Core application which will
be executed sequentially. The Run method adds a terminal middleware so it cannot call next
middleware as it would be the last middleware in a sequence. The following will always execute
the first Run method and will never reach the second Run method.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World From 1st Middleware");
});

// the following will never be executed


app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World From 2nd Middleware");
});
}

To configure multiple middleware, use Use() extension method. It is similar to Run() method
except that it includes next parameter to invoke next middleware in the sequence. Consider the
following example.

Example: Use()
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello World From 1st Middleware!");

await next();
});

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World From 2nd Middleware");
});
}

The above example will display Hello World From 1st Middleware!Hello World From
2nd Middleware! in the browser.

Thus, we can use Use() method to configure multiple middlewares in the order we like.

Add Built-in Middleware Via NuGet


ASP.NET Core is a modular framework. We can add server side features we need in our
application by installing different plug-ins via NuGet. There are many middleware plug-ins
available which can be used in our application.

The followings are some built-in middleware:

Middleware Description
Authentication Adds authentication support.
CORS Configures Cross-Origin Resource Sharing.
Routing Adds routing capabilities for MVC or web form
Session Adds support for user session.
StaticFiles Adds support for serving static files and directory browsing.
Diagnostics Adds support for reporting and handling exceptions and errors.
Let's see how to use Diagnostics middleware.

Diagnostics Middleware
Let's install and use Diagnostics middleware. Diagnostics middleware is used for reporting and
handling exceptions and errors in ASP.NET Core, and diagnosing Entity Framework Core
migrations errors.

Open project.json and add Microsoft.AspNetCore.Diagnostics dependency if it is not added.


Wait for some time till Visual Studio restores the packages.

This package includes following middleware and extension methods for it.

Middleware Extension Method Description


Captures synchronous and
asynchronous exceptions
DeveloperExceptionPageMiddleware UseDeveloperExceptionPage() from the pipeline and
generates HTML error
responses.
Catch exceptions, log them
ExceptionHandlerMiddleware UseExceptionHandler() and re-execute in an
alternate pipeline.
Check for responses with
StatusCodePagesMiddleware UseStatusCodePages() status codes between 400
and 599.
Display Welcome page for
WelcomePageMiddleware UseWelcomePage()
the root path.

We can call respective Use* extension methods to use the above middleware in the configure
method of Startup class.

Let's add welcomePage middleware which will display welcome page for the root path.

Example: Add Diagnostics Middleware


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseWelcomePage();
//other code removed for clarity
}

The above example will display the following welcome page for each request.
This way we can use different Use* extension methods to include different middleware.

Next, learn how to implement logging functionality in the ASP.NET Core application.

 Add Custom Middleware in ASP.NET


Core Application
 Here, you will learn how to create and add your own custom middleware into the request
pipeline of ASP.NET Core application.
 The custom middleware component is like any other .NET class with Invoke() method.
However, in order to execute next middleware in a sequence, it should have
RequestDelegate type parameter in the constructor.
 Visual Studio includes template for creating standard middleware class. For this, right
click on the project or folder where you want to create middleware class and select Add
-> New Item. This will open Add New Item popup. Search for word "middleware" in the
top right search box as shown below.

Add Custom Middleware


 Select Middleware Class item and give it a name and click on Add button. This will add a
new class for the middleware with extension method as shown below.
 Example: Custom Middleware
 // 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>();
 }
 }
 As you can see above, the Invoke() method is not asynchronous. So, change it to
asynchronous and write your custom logic before calling next();
 Example: Async Middleware
 public class MyMiddleware
 {
 private readonly RequestDelegate _next;
 private readonly ILogger _logger;

 public MyMiddleware(RequestDelegate next, ILoggerFactory logFactory)
 {
 _next = next;

 _logger = logFactory.CreateLogger("MyMiddleware");
 }

 public async Task Invoke(HttpContext httpContext)
 {
 _logger.LogInformation("MyMiddleware executing..");

 await _next(httpContext); // calling next middleware

 }
 }

 // 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>();
 }
 }
 Add Custom Middleware
 Now, we need to add our custom middleware in the request pipeline by using Use
extension method as shown below.
 Example: Add Middleware into Request Pipeline
 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
 app.UseMyMiddleware();

 app.Run(async (context) =>
 {
 await context.Response.WriteAsync("Hello World!");
 });
 }
 We can add middleware using app.UseMiddleware<MyMiddleware>() method of
IApplicationBuilder also.
 Thus, we can add custom middleware in the ASP.NET Core application.

You might also like