
Here, once an HTTP request comes at the ASP.NET server, the server will delegate the request to the first middleware in our application. Each middleware has the option of creating a response, or calling the next middleware. Basically, it's a bi-directional pipeline. Therefore, if the first component passes the request to the next middleware, the first component will see a response coming out of the other components. Each Middleware has got specific sets of functionalities. Now, let’s see how to configure Middleware. Let me create one empty project as shown below. Here, I am using Visual Studio 2017 RC Version. You can use VS-2015 as well.



- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- namespace Custom_Midlleware
- {
- public class Startup
- {
- // 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 https://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, IHostingEnvironment env, ILoggerFactory loggerFactory)
- {
- loggerFactory.AddConsole();
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello World!");
- });
- }
- }
- }

Obviously, first it will hit ConfigureServices to check if any component has been requested, later on it will go to the pipeline section and execute the same in linear ordering.
Note
Ordering of Midlleware is very important. We will explore this in the coming section.
After above execution, it simply produced Hello World text in browser.
Now, if you look closely at this Run method, it accepts RequestDelegate as a parameter whose signature accepts one parameter as a HTTP Context and return type is Task as shown below.
Now, what this middleware component is doing is it's handling all the requests made to the app and sending back the response. Run method adds as a RequestDelegate which is terminal to the request pipeline. This means any middleware comes after this; it won’t be reached. At the moment, we don’t have much in the middleware section. Let’s go ahead and add one. Below is the structure for that.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- namespace Custom_Midlleware
- {
- public class Startup
- {
- // 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 https://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, IHostingEnvironment env, ILoggerFactory loggerFactory)
- {
- loggerFactory.AddConsole();
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello World!");
- });
- app.Use(async (context, next) =>
- {
- await context.Response.WriteAsync("First Middleware!");
- await next.Invoke();
- });
- }
- }
- }

This is why the ordering of Middleware is very important. Run is a terminal middleware, which terminates the middleware chain, hence our new middleware couldn’t reach it. Middlewares always executes from top to bottom. Hence, let’s place the same before Run method.


Now, we are going to delve further. Here, we will focus on other methods available to us like
- Map
- MapWhen
Let’s start with Map. Map has two parameters. Below is the concrete structure for the same.


Notic, the last line; this came from the first middleware after context returns from terminal middleware. Now, let’s go ahead and provide the map. In this case, it will produce the following output.

One thing to notice here, it didn’t go outside Map. Here is the thing, if you are using Map extension, it won’t land in terminal middleware outside Map branch. It will automatically terminate that. It won’t even need Run inside Map to terminate the pipeline. I have used it here, just to print the message. Let me comment the same. Now my code looks like,


It means, it printed the first line from 1st middleware, which is Use extension, then it invoked the next middleware which is Map extension, where it matched the path. Upon successful match, it just terminated the pipeline and returned the result in browser. Now, let’s go ahead and see the structure of MapWhen.



Similarly, If I don’t keep terminal middleware inside our MapWhen extension, then also it will get terminated and below is the result for the same.


I can also go ahead and use middleware inside middleware like shown below.




Below is the finished code for the same.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- namespace Custom_Midlleware
- {
- public class Startup
- {
- // 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 https://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, IHostingEnvironment env, ILoggerFactory loggerFactory)
- {
- loggerFactory.AddConsole();
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.Use(async (context, next) =>
- {
- await context.Response.WriteAsync("First Middleware! <br/>");
- await next.Invoke();
- await context.Response.WriteAsync("While returning from Run!! <br/>");
- });
- app.Map("/myview", (builder) =>
- {
- builder.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello From Map Component!<br/>");
- });
- });
- app.MapWhen(context => context.Request.Query.ContainsKey("something"), (builder) =>
- {
- builder.Use(async (context, next) =>
- {
- await context.Response.WriteAsync("Using Use Extension from MapWhen extension!!<br/>");
- await next.Invoke();
- });
- builder.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hi, From MapWhen Extension!<br/>");
- });
- });
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello World!<br/>");
- });
- }
- }
- }






Maruthi PalllamalliPosted Feb 13, 2017, 5:17 AM
Was this similar to owin middleware ? seems to be same. What is the difference between this nutshell and owin ? will it allow self hosting ?