練習 - 建立自訂中介軟體

已完成

開發人員可以建立自訂中介軟體元件,以在 ASP.NET Core 應用程式中新增功能。 自訂中介軟體可以插入到中介軟體管線中的任何位置,並可與內建的中介軟體元件搭配使用,如下列範例所示:

此圖顯示要求通過管線的流程。

貴公司的網路營運小組正在針對生產環境中的效能問題進行疑難排解。 小組負責人請您實作一些功能,以便更好地支援應用程式的即時監視。 此應用程式應該將要求詳細資料記錄到主控台。 針對每個要求,其應該記錄要求方法、路徑和回應狀態碼。

在此練習中,您會建立自訂的中介軟體元件,以將要求詳細資料記錄到主控台。

新增自訂中介軟體

讓我們修改現有的 ASP.NET Core 應用程式,以納入會將要求詳細資料記錄到主控台的自訂中介軟體。

  1. 如果 Program.cs 檔案尚未開啟,請開啟該檔案。

  2. app.Run() 正前方,插入下列程式碼:

    app.Use(async (context, next) =>
    {
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
        await next(); 
    });
    

    在上述程式碼中:

    • app.Use() 會將自訂中介軟體元件新增至管線。 該元件採用 HttpContext 物件和 RequestDelegate 物件作為參數。
    • 委派會將要求方法、路徑和回應狀態碼寫入到主控台。
    • await next() 會呼叫管線中的下一個中介軟體元件。

測試變更

  1. Ctrl+Shift+F5 重建並重新啟動應用程式。

  2. 當瀏覽器視窗開啟時,請注意根 URL 顯示「Welcome to Contoso!」

  3. /history 新增至 URL,然後按 Enter 鍵。 瀏覽器會重新導向至 /about 頁面。

  4. 在 Visual Studio Code 中,按 Ctrl+Shift+P 以開啟命令選擇區。 搜尋並選取 [偵錯主控台:聚焦在 [偵錯主控台] 檢視],以切換至底部面板中的 [偵錯主控台] 索引標籤。 請注意下列幾行:

    GET / 200
    GET /about 200
    

    主控台輸出會顯示每個要求的要求方法、路徑和回應狀態碼。 第一行顯示根 URL 的要求,第二行顯示 /about 頁面的要求。

    注意

    您的瀏覽器可能也會要求 /favicon.ico。 這是網站最愛圖示的標準要求,可予以忽略。

  5. 讓應用程式保持執行以便進行下一個練習。

變更中介軟體的順序

應用程式似乎能正常運作,但有個問題。 您要求的是 /history 頁面,但主控台輸出未顯示該頁面。 會有此行為是因為負責記錄要求詳細資料的自訂中介軟體元件新增到 URL 重寫器中介軟體之後。 URL 重寫器中介軟體會將要求從 /history 重新導向至 /about 並傳送回應,自訂中介軟體元件未看到該要求。 讓我們來修正此錯誤。

  1. 將您新增的 app.Use() 行移到 app.UseRewriter() 行正前面。

    完整的 Program.cs 檔案看起來應該如下:

    using Microsoft.AspNetCore.Rewrite;
    
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.Use(async (context, next) =>
    {
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
        await next(); 
    });
    
    app.UseRewriter(new RewriteOptions().AddRedirect("history", "about"));
    
    app.MapGet("/", () => "Hello World!");
    app.MapGet("/about", () => "Contoso was founded in 2000.");
    
    app.Run();
    

    現在,自訂中介軟體元件會新增到 URL 重寫器中介軟體之前。 自訂中介軟體元件會在 URL 重寫器中介軟體處理要求並重新導向要求之前,記錄該要求的詳細資料。

  2. 再次重新啟動應用程式,並像之前一樣地進行測試。 這次,偵錯主控台輸出應該會包含 /history 頁面的要求。

    GET / 200
    GET /history 200
    GET /about 200
    

    主控台輸出現在會在重新導向至 /history 頁面之前,先顯示 /about 頁面的要求。

修正狀態碼

應用程式已幾乎準備就緒,但還有一個問題。 主控台輸出中的狀態碼一律為 200,即使應用程式重新導向要求也一樣。 /history 要求的狀態碼應該是 302 重新導向。 有此行為的原因是有另一個中介軟體元件處理順序問題。

自訂中介軟體元件會將詳細資料記錄至主控台,然後呼叫 await next() 以前往到下一個中介軟體元件。 問題是,在終端中介軟體元件開始回應之後,系統會設定 StatusCode 物件的 Response 屬性。 讓我們變更程式碼以修正此問題。

  1. 在您新增的委派中,將 Console.WriteLine() 行移到 await next() 行之後。

    更新後的程式碼看起來應該如下:

    app.Use(async (context, next) =>
    {
        await next(); 
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
    });
    

    現在,自訂中介軟體元件會在終端中介軟體元件設定回應狀態碼之後,記錄該要求的詳細資料。

  2. 再次重新啟動並測試 /history 要求。 偵錯主控台輸出現在應該會顯示正確的狀態碼了。

    GET / 200
    GET /history 302
    GET /about 200