一、什么是中间件?
中间件是一种装配到应用管道以处理请求和响应的软件。中间件可以有多个,每个组件可以选择是否将请求传递到管道中的下一个组件;可在管道中的下一个组件前后执行工作。在ASP.NET Core中使用IApplicationBuilder来创建中间件管道。下面是官方给出的中间件管道请求图:
二、中间件的使用
在默认情况下,中间件的执行顺序是根据Startup.cs文件中,在public void Configure(IApplicationBuilder app){}方法中注册的先后顺序执行。
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Do work that doesn't write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
}
}
app.Use()是由IApplicationBuilder接口原生提供的,它将多个请求委托链接在一起,通过next.Invoke()方法来调用下一个中间件,如果不调用的话,则会造成管道短路。
app.Run()是一个扩展方法,它需要一个RequestDelegate委托,里面包含了Http的上下文信息,它拦截了所有的请求,返回一段文本作为响应,它总在管道的最后执行。因为Run()终止了管道的运行,因此也叫作终端中间件。
public class Startup
{
private static void HandleMapTest1(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 1");
});
}
private static void HandleMapTest2(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 2");
});
}
public void Configure(IApplicationBuilder app)
{
app.Map("/map1", HandleMapTest1);
app.Map("/map2", HandleMapTest2);
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
});
}
}
app.Map()是一个拓展方法,类似于MVC中的路由,主要是用于一些特殊请求的路径处理。
三、常见中间件组件
- 异常/错误处理
-
当应用在开发环境中运行时:
1)开发人员异常页中间件 (UseDeveloperExceptionPage)报告应用运行时错误。
2)数据库错误页中间件报告数据库运行时错误。
-
当应用在生产环境中运行时:
1)异常处理程序中间件(UseExceptionHandler) 捕获以下中间件中引发的异常。
2)HTTP严格传输安全协议 (HSTS) 中间件 (UseHsts) 添加 Strict-Transport-Security 标头。
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- 静态文件中间件 (UseStaticFiles) 返回静态文件,并简化进一步请求处理。
- Cookie 策略中间件 (UseCookiePolicy) 使应用符合欧盟一般数据保护条例 (GDPR)规定。
- 用于路由请求的路由中间件 (UseRouting)。
- 身份验证中间件 (UseAuthentication) 尝试对用户进行身份验证,然后才会允许用户访问安全资源。
- 用于授权用户访问安全资源的授权中间件 (UseAuthorization)。
- 会话中间件 (UseSession) 建立和维护会话状态。 如果应用使用会话状态,请在 Cookie 策略中间件之后和 MVC中间件之前调用会话中间件。
- 用于将 Razor Pages 终结点添加到请求管道的终结点路由中间件(带有 MapRazorPages 的 UseEndpoints)。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}