中間件是被用到管道(pipeline)上來處理請求(request)和響應的(response)。 asp.net core 本身提供了一些內置的中間件,但是有一些場景,你可能會需要寫一些自定義的中間件。 1. 創建一個使用匿名委托的中間件組件的形式 註:app.use中return next()會 ...
中間件是被用到管道(pipeline)上來處理請求(request)和響應的(response)。
asp.net core 本身提供了一些內置的中間件,但是有一些場景,你可能會需要寫一些自定義的中間件。
1. 創建一個使用匿名委托的中間件組件的形式
public class Startup { public void Configure(IApplicationBuilder app) { app.Use((context, next) => { var cultureQuery = context.Request.Query["culture"]; if (!string.IsNullOrWhiteSpace(cultureQuery)) { var culture = new CultureInfo(cultureQuery); CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture; } // Call the next delegate/middleware in the pipeline return next(); }); app.Run(async (context) => { await context.Response.WriteAsync( $"Hello {CultureInfo.CurrentCulture.DisplayName}"); }); } }
註:app.use中return next()會傳遞到下一個中間件繼續執行;而僅僅只使用app.use 的用法和app.run相同,即不會再傳遞到下一個中間件,在此作為請求處理的結束
2.把中間件的委托封裝到類裡面,即把中間件寫成一個類的形式
using Microsoft.AspNetCore.Http; using System.Globalization; using System.Threading.Tasks; namespace Culture { public class RequestCultureMiddleware { private readonly RequestDelegate _next; public RequestCultureMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { var cultureQuery = context.Request.Query["culture"]; if (!string.IsNullOrWhiteSpace(cultureQuery)) { var culture = new CultureInfo(cultureQuery); CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture; } // Call the next delegate/middleware in the pipeline await _next(context); } } }
然後,再使用一個中間件擴展方法,通過IApplicationBuilder使用中間件
using Microsoft.AspNetCore.Builder; namespace Culture { public static class RequestCultureMiddlewareExtensions { public static IApplicationBuilder UseRequestCulture( this IApplicationBuilder builder) { return builder.UseMiddleware<RequestCultureMiddleware>(); } } }
最後,在 Startup.Configure 中調用中間件
public class Startup { public void Configure(IApplicationBuilder app) { app.UseRequestCulture(); //調用中間件 app.Run(async (context) => { await context.Response.WriteAsync( $"Hello {CultureInfo.CurrentCulture.DisplayName}"); }); } }
另外,這裡還有一點,這個地方不是很懂,說下自己的理解,歡迎大佬指正
當中間件中註入的還有其他service(官方叫 a scoped service )時,需要使用的是Invoke方法,而不是InvokeAsync方法
public class CustomMiddleware { private readonly RequestDelegate _next; public CustomMiddleware(RequestDelegate next) { _next = next; } // IMyScopedService is injected into Invoke public async Task Invoke(HttpContext httpContext, IMyScopedService svc) { svc.MyProperty = 1000; await _next(httpContext); } }
這裡,Invoke和InvokeAsync是不是相同,還是說就僅僅是命名不同,其他用法都一樣?
歡迎指正
參考網址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-2.2