湖南建设银行网站,济南做兼职网站,搜索网站老是跳出别的网站要怎么做,仿别人的网站点击上方蓝字关注“汪宇杰博客”导语本文教大家如何在 .NET Core 应用中使用中间件输出路由信息以便调试程序。背景在 .NET Framework 的上古时代#xff0c;有个叫做 RouteDebugger 的神器#xff0c;可以在 MVC 或 Web API 应用中输出当前页面的路由信息#xff0c;也可查… 点击上方蓝字关注“汪宇杰博客”导语本文教大家如何在 .NET Core 应用中使用中间件输出路由信息以便调试程序。背景在 .NET Framework 的上古时代有个叫做 RouteDebugger 的神器可以在 MVC 或 Web API 应用中输出当前页面的路由信息也可查看应用中注册的所有路由信息。它的 NuGet 包routedebugger最新版是 2.1.5更新于 2016年源于 Phil Haack 大神12年前的文章 https://haacked.com/archive/2008/03/13/url-routing-debugger.aspx 这个包可以非常直观的在浏览器访问应用的时候直接在页面最下方输出当前的路由信息以及全部的路由表。以便于在复杂的应用中帮助程序员摆脱 996。.NET Core 怎么办12年后已经是 .NET Core 的天下了显然由于运行机制的不同.NET Core 无法使用 RouteDebugger 或者改造它的代码只能重写。虽然社区已经有人写了一份 AspNetCoreRouteDebugger 但是这个项目有几个明显的问题https://github.com/ardalis/AspNetCoreRouteDebugger使用不方便项目需要用户手工拷贝它的两个文件 Routes.cshtmlRoutes.cshtml.cs 到自己的工程。并且要自己修改命名空间、做访问限制等。你以为是 996 的结束其实是 007 的开始。另外项目默认提供的是 Razor Page 方案在不使用 Razor Page 的项目里还需要继续手工拷它的 Routes2Controller 去使用。 只能输出全部路由原版 RouteDebugger 解决的最重要的问题之一就是输出当前页面的路由因为不是每个公司都按照 MVC 的默认 convention 做项目很可能URL和 Controller / View 对应不起来程序员接到需求要改代码很可能找不到改哪个 Action所以才用 RouteDebugger。而该 .NET Core 项目只能输出全部路由表而不是当前页面的路由使用场景很有限。没有 NuGet 包一旦项目有更新用户必须时刻关注作者 GitHub 才行并需要手工更新代码非常不方便。综上所述我决定自己再写一个 RouteDebugger。它需要做到以下几点.NET Corelish既然用了 .NET Core就要用出精髓。.NET Core 的精髓之一在于中间件Middleware而获取路由信息并输出显然最适合用中间件去做以尽可能的对业务代码实现 0 侵入。不要输出到页面末尾在用户的页面末尾输出debug信息看上去很方便但实际项目中在极端场景下可能会破坏页面的功能和显示样式尤其是页面加载了三方统计、样式修改插件等。更别说遇到SPA项目了页面呈现的原理都不一样所以输出到页面这套方法已经过时。目前我觉得输出到 HTTP Response Header 是更好的做法不仅不会影响页面功能及显示效果对工具CURL、浏览器F12等支持也更加友好。JSON over HTML TableJson 是当今世界的政治正确它比起 HTML Table更面向程序员有更好的工具适配。因此不管是输出当前路由还是全部路由表我都选择了 JSON 格式。自主研发成功如果你并不想了解怎么写只想拿来就用的话我已将工程打包成 NuGet 包并开源https://github.com/EdiWang/AspNetCore-RouteDebuggerMiddlewaredotnet add package Edi.RouteDebugger只要添加到自己应用的请求管线即可推荐仅用于开发环境if (env.IsDevelopment()){ app.UseRouteDebugger();}这里要注意顺序ASP.NET Core 的中间件顺序有讲究得写在 app.UseEndpoints() 及 app.UseRouting() 的上面。具体原因可参考微软官方文档对中间件的介绍https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/接下来打开应用中任意一个页面只要它有路由信息就能在 Header 里看见若要查看全部路由表访问 /route-debugger 即可代码解析想要获取当前请求的路由信息只要调用 HttpContext 对象的 GetRouteData() 方法即可。然后序列化为 Json 输出到 Response Header。由于我们得先执行 _next(context) 才能得到非空的路由信息而这部操作会导致 HTTP Reponse已经开始输出从而导致 Header 只读所以需要一些 workaround 来设置 Header。最终代码如下private async Task SetCurrentRouteInfo(HttpContext context){ var originalBodyStream context.Response.Body; await using var responseBody new MemoryStream(); context.Response.Body responseBody; await _next(context); context.Response.Body.Seek(0, SeekOrigin.Begin); await new StreamReader(context.Response.Body).ReadToEndAsync(); context.Response.Body.Seek(0, SeekOrigin.Begin); var rd context.GetRouteData(); if (null ! rd rd.Values.Any()) { var rdJson JsonSerializer.Serialize(rd.Values); context.Response.Headers[current-route] rdJson; } await responseBody.CopyToAsync(originalBodyStream);}获取全部路由信息得注入一个 IActionDescriptorCollectionProvider 对象好在 Middleware class 的构造函数可以直接无脑注入。public async Task Invoke(HttpContext context, IActionDescriptorCollectionProvider provider null){ if (context.Request.Path /route-debugger) { if (null ! provider) { var routes provider.ActionDescriptors.Items.Select(x new { Action x.RouteValues[Action], Controller x.RouteValues[Controller], Name x.AttributeRouteInfo?.Name, Template x.AttributeRouteInfo?.Template, Contraint x.ActionConstraints }).ToList(); var routesJson JsonSerializer.Serialize(routes); context.Response.ContentType application/json; await context.Response.WriteAsync(routesJson, Encoding.UTF8); } else { await context.Response.WriteAsync(IActionDescriptorCollectionProvider is null, Encoding.UTF8); } } else { await SetCurrentRouteInfo(context); }}目前这个 .NET Core 版的 RouteDebugger 功能还非常基础非常欢迎大家提建议或PR。汪宇杰博客.NET | Azure | 微软MVP长按扫码关注我们