日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

自制 .NET Core 路由调试中间件

發布時間:2023/12/4 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自制 .NET Core 路由调试中间件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊上方藍字關注“汪宇杰博客”

導語

本文教大家如何在 .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.cshtml,Routes.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 Table

    Json 是當今世界的政治正確,它比起 HTML Table,更面向程序員,有更好的工具適配。因此不管是輸出當前路由還是全部路由表,我都選擇了 JSON 格式。

    自主研發成功

    如果你并不想了解怎么寫,只想拿來就用的話,我已將工程打包成 NuGet 包,并開源:

    https://github.com/EdiWang/AspNetCore-RouteDebuggerMiddleware

    dotnet 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

    長按掃碼關注我們

    總結

    以上是生活随笔為你收集整理的自制 .NET Core 路由调试中间件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。