ASP.NET Core - Middleware

In this chapter, we will understand how to set up middleware. Middleware in ASP.NET Core controls how our application responds to HTTP requests. It can also control how our application looks when there is an error, and it is a key piece in how we authenticate and authorize a user to perform specific actions.
Middleware are software components that are assembled into an application pipeline to handle requests and responses.
Middleware are software components that are assembled into an application pipeline to handle requests and responses.
Each component chooses whether to pass the request on to the next component in the pipeline, and can perform certain actions before and after the next component is invoked in the pipeline.
Each component chooses whether to pass the request on to the next component in the pipeline, and can perform certain actions before and after the next component is invoked in the pipeline.
Request delegates are used to build the request pipeline. The request delegates handle each HTTP request.
Request delegates are used to build the request pipeline. The request delegates handle each HTTP request.
Each piece of middleware in ASP.NET Core is an object, and each piece has a very specific, focused, and limited role.
Each piece of middleware in ASP.NET Core is an object, and each piece has a very specific, focused, and limited role.
Ultimately, we need many pieces of middleware for an application to behave appropriately.
Ultimately, we need many pieces of middleware for an application to behave appropriately.
Let us now assume that we want to log information about every request into our application.
In that case, the first piece of middleware that we might install into the application is a logging component.
In that case, the first piece of middleware that we might install into the application is a logging component.
This logger can see everything about the incoming request, but chances are a logger is simply going to record some information and then pass along this request to the next piece of middleware.
This logger can see everything about the incoming request, but chances are a logger is simply going to record some information and then pass along this request to the next piece of middleware.
Middleware is a series of components present in this processing pipeline.
Middleware is a series of components present in this processing pipeline.
The next piece of middleware that we've installed into the application is an authorizer.
The next piece of middleware that we've installed into the application is an authorizer.
An authorizer might be looking for specific cookie or access tokens in the HTTP headers.
An authorizer might be looking for specific cookie or access tokens in the HTTP headers.
If the authorizer finds a token, it allows the request to proceed. If not, perhaps the authorizer itself will respond to the request with an HTTP error code or redirect code to send the user to a login page.
If the authorizer finds a token, it allows the request to proceed. If not, perhaps the authorizer itself will respond to the request with an HTTP error code or redirect code to send the user to a login page.
But, otherwise, the authorizer will pass the request to the next piece of middleware which is a router.
But, otherwise, the authorizer will pass the request to the next piece of middleware which is a router.
A router looks at the URL and determines your next step of action.
A router looks at the URL and determines your next step of action.
The router looks over the application for something to respond to and if the router doesn't find anything to respond to, the router itself might return a 404 Not Found error.
The router looks over the application for something to respond to and if the router doesn't find anything to respond to, the router itself might return a 404 Not Found error.
Let us now take a simple example to understand more about middleware. We set up the middleware in ASP.NET using the Configure method of our Startup class.
using Microsoft.AspNet.Builder; 
using Microsoft.AspNet.Hosting; 
using Microsoft.AspNet.Http; 

using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.Configuration;  

namespace FirstAppDemo { 
   public class Startup { 
      public Startup() { 
         var builder = new ConfigurationBuilder() 
            .AddJsonFile("AppSettings.json"); 
         Configuration = builder.Build(); 
      }  
      public IConfiguration Configuration { get; set; }  
       
      // This method gets called by the runtime. 
      // Use this method to add services to the container. 
      // For more information on how to configure your application, 
      // visit http://go.microsoft.com/fwlink/?LinkID=398940 
      public void ConfigureServices(IServiceCollection services) { 
      }  
      
      // This method gets called by the runtime.  
      // Use this method to configure the HTTP request pipeline. 
      public void Configure(IApplicationBuilder app) { 
         app.UseIISPlatformHandler();  
         
         app.Run(async (context) => { 
            var msg = Configuration["message"]; 
            await context.Response.WriteAsync(msg); 
         });  
      }  
      // Entry point for the application. 
      public static void Main(string[] args) => WebApplication.Run<Startup>(args); 
   } 
} 
Inside the Configure() method, we will invoke the extension methods on the IApplicationBuilder interface to add middleware.
There are two pieces of middleware in a new empty project by default −
IISPlatformHandler
Middleware registered with app.Run
IISPlatformHandler allows us to work with Windows authentication. It will look at every incoming request and see if there is any Windows identity information associated with that request and then it calls the next piece of middleware.
The next piece of middleware in this case is a piece of middleware registered with app.Run. The Run method allows us to pass in another method, which we can use to process every single response. Run is not something that you will see very often, it is something that we call a terminal piece of middleware.
Middleware that you register with Run will never have the opportunity to call another piece of middleware, all it does is receive a request, and then it has to produce some sort of response.
You also get access to a Response object and one of the things you can do with a Response object is to write a string.
If you want to register another piece of middleware after app.Run, that piece of middleware would never be called because, again, Run is a terminal piece of middleware. It will never call into the next piece of middleware.
Let us proceed with the following steps to add another middleware −
Step 1 − To add another middleware, right-click on project and select Manage NuGet Packages.
Step 2 − Search for Microsoft.aspnet.diagnostics that is actually ASP.NET Core middleware for exception handling, exception display pages, and diagnostics information. This particular package contains many different pieces of middleware that we can use.
Step 3 − Install that package if it is not installed in your project.
Step 4 − Let us now go to the Configure() method and invoke app.UseWelcomePage middleware.
// This method gets called by the runtime.  
// Use this method to configure the HTTP request pipeline. 
public void Configure(IApplicationBuilder app) { 
   app.UseIISPlatformHandler(); 
   app.UseWelcomePage();  
   
   app.Run(async (context) => { 
      var msg = Configuration["message"]; 
      await context.Response.WriteAsync(msg); 
   });  
}
Step 5 − Run your application and you will see the following welcome screen.
This Welcome screen might not be as useful.
Step 6 − Let us try something else that might be a little more useful. Instead of using the Welcome page, we will use the RuntimeInfoPage.
// This method gets called by the runtime.  
// Use this method to configure the HTTP request pipeline. 
public void Configure(IApplicationBuilder app) { 
   app.UseIISPlatformHandler(); 
   app.UseRuntimeInfoPage();  
   
   app.Run(async (context) => { 
      var msg = Configuration["message"]; 
      await context.Response.WriteAsync(msg); 
   });  
}
Step 7 − Save your Startup.cs page and refresh your browser and you will see the following page.
This RuntimeInfoPage is a middleware that will only respond to requests that come in for a specific URL. If the incoming request does not match that URL, this piece of middleware just lets the request pass through to the next piece of middleware. The request will pass through the IISPlatformHandler middleware, then go to the UseRuntimeInfoPage middleware. It is not going to create a response, So it will go to our app.Run and display the string.
Step 8 − Let us add “/runtimeinfo” at the end of your URL. You will now see a page that is produced by that runtime info page middleware.
You will now see a response that gives you some information about your runtime environment such as the Operating System, runtime version, architecture, type and all the packages that you are using etc.