我們可以使用ASP.NET Core的中間件來實現Url rewrite功能,下面我們定義一個中間件ReplaceQueryStringMiddleware來替換Http請求中的Url參數即QueryString,這相當於就是要用到以前ASP.NET的Url rewrite功能。
中間件ReplaceQueryStringMiddleware類:
public class ReplaceQueryStringMiddleware { private readonly RequestDelegate next; public ReplaceQueryStringMiddleware(RequestDelegate next) { this.next = next; } public async Task Invoke( Microsoft.AspNetCore.Http.HttpContext context) { var request = context.Request; var queryString = request.QueryString.Value; if (!string.IsNullOrWhiteSpace(queryString)) { //如果這里給context.Request.QueryString或context.Request.Path重新賦值,相當於就是Url rewrite了 request.QueryString = new QueryString("?demoKey=demoValue");//注意前面要加上問號,否者會報異常 } await next.Invoke(context); } }
中間件ReplaceQueryString的擴展類ReplaceQueryStringMiddlewareExtension:
public static class ReplaceQueryStringMiddlewareExtension { public static void UseReplaceQueryString(this IApplicationBuilder app) { app.UseMiddleware<ReplaceQueryStringMiddleware>(); } }
Startup類的Configure方法中啟用ReplaceQueryString中間件
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { //啟用ReplaceQueryString中間件 app.UseReplaceQueryString(); //因為我們在app.UseMvc之前調用了app.UseReplaceQueryString將URL的QueryString替換了,所以下面使用app.UseMvc后,在MVC Controller中用Request.QueryString讀到的將會是替換后的"?demoKey=demoValue" //同樣如果在app.UseReplaceQueryString中更改了context.Request.Path的值,那么在下面app.UseMvc后,MVC讀到的Request.Path也是更改后新的Url值,這會導致MVC根據新的Url來調用不同的Controller和Action,實現了Url rewrite的功能 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
效果:
此外,如果是一些簡單的Url rewrite,那么直接在Startup類的Configure方法中用ASP.NET Core自帶的中間件app.UseRewriter即可。
注意,從ASP.NET Core 3.X開始,在Startup類的Configure方法中,app.UseReplaceQueryString要放在app.UseRouting前面,這樣如果在app.UseReplaceQueryString中更改了context.Request.Path的值,ASP.NET Core MVC才會根據新的Url來調用不同的Controller和Action,來實現Url rewrite的功能:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseReplaceQueryString(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }