Run 方法
Run 方法源码:
/// <summary>
/// Adds a terminal middleware delegate to the application's request pipeline.
/// </summary>
/// <param name="app">The <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" /> instance.</param>
/// <param name="handler">A delegate that handles the request.</param>
public static void Run(this IApplicationBuilder app, RequestDelegate handler)
{
if (app == null)
throw new ArgumentNullException(nameof (app));
if (handler == null)
throw new ArgumentNullException(nameof (handler));
app.Use((Func<RequestDelegate, RequestDelegate>) (_ => handler));
}
不难看出 Run 方法就是专门用来添加 terminal middleware(终端中间件)的。
一个管道中通常只有一个终端中间件。
Use 方法
Use 源码:
/// <summary>
/// Adds a middleware delegate defined in-line to the application's request pipeline.
/// </summary>
/// <param name="app">The <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" /> instance.</param>
/// <param name="middleware">A function that handles the request or calls the given next function.</param>
/// <returns>The <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" /> instance.</returns>
public static IApplicationBuilder Use(
this IApplicationBuilder app,
Func<HttpContext, Func<Task>, Task> middleware)
{
return app.Use((Func<RequestDelegate, RequestDelegate>) (next => (RequestDelegate) (context =>
{
Func<Task> func = (Func<Task>) (() => next(context));
return middleware(context, func);
})));
}
Use 用于在管道中添加 in-line(内联定义的)中间件。
请求管道
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Use(async (context, next) =>
{
context.Response.ContentType = "text/plain;charset=utf-8";
logger.LogInformation("MW1: 传入请求");
await next();
logger.LogInformation("MW1: 传出响应");
});
app.Use(async (context, next) =>
{
logger.LogInformation("MW2: 传入请求");
await next();
logger.LogInformation("MW2: 传出响应");
});
app.Run(async (context) =>
{
logger.LogInformation("MW3: 传入请求");
await context.Response.WriteAsync("MW3:处理请求,并生成响应");
logger.LogInformation("MW3: 传出响应");
});
}
输出:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:3290/
StudentManagement.Startup:Information: MW1: 传入请求
StudentManagement.Startup:Information: MW2: 传入请求
StudentManagement.Startup:Information: MW3: 传入请求
StudentManagement.Startup:Information: MW3: 传出响应
StudentManagement.Startup:Information: MW2: 传出响应
StudentManagement.Startup:Information: MW1: 传出响应
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 29.7525ms 200 text/plain;charset=utf-8
- 所有的请求处理都会在每个中间件组件调用 next() 方法之前触发。请求按照途中箭头所示,依次穿过所有管道
- 当(终端)中间件处理请求并产生响应时,请求流程会在管道开始反向传递