了解中介軟體

已完成

Web 應用程式的目的是接收和回應 HTTP 要求。 收到要求後,然後伺服器會產生適當的回應。 ASP.NET Core 中的所有內容都與此要求/回應循環過程有關。

當 ASP.NET Core 應用程式收到 HTTP 要求時,它會經過一系列的元件來產生回應。 這些元件稱為中介軟體。 中介軟體可以被視為是要求流經的管線,而每個中介軟體層都可以在管線中的下一層之前和之後執行程式碼。

描述 HTTP 請求經過多個中間件的圖表。

中介軟體和委派

中介軟體會作為接受 HttpContext 物件並傳回 Task 的委派來加以實作。 HttpContext 物件代表目前的要求和回應。 委派是處理要求和回應的函式。

例如,請考慮下列程式碼:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

在上述程式碼中:

  • WebApplication.CreateBuilder(args) 會建立新的 WebApplicationBuilder 物件。
  • builder.Build() 會建立新的 WebApplication 物件。
  • 第一個 app.Run() 定義了一個委派,該委派接受一個 HttpContext 物件並回傳一個 Task。 該委派將 "Hello world!" 寫入回應中。
  • 第二個 app.Run() 會啟動應用程式。

當應用程式收到 HTTP 要求時,會呼叫該委派。 該委派將 "Hello world!" 寫入回應中並完成要求。

鏈結中介軟體

在大部分的應用程式中,您會有多個按順序執行的中介軟體元件。 您將中介軟體元件新增至管線的順序很重要。 元件會按照它們被新增的順序執行。

終端和非終端的中介軟體

每個中介軟體都可以被視為是終端或非終端的中介軟體。 非終端的中介軟體會處理要求,然後呼叫管線中的下一個中介軟體。 終端的中介軟體是管線中的最後一個中介軟體,而它沒有下一個中介軟體可供呼叫。

使用 app.Use() 新增的委派可以是終端或非終端的中介軟體。 這些委派需要一個 HttpContext 物件和一個 RequestDelegate 物件作為參數。 通常,委派包括 await next.Invoke();。 這會將控制權傳遞給管線上的下一個中介軟體。 該行之前的程式碼會在下一個中介軟體之前執行,而該行之後的程式碼會在下一個中介軟體之後執行。 使用 app.Use() 新增的委派在將回應傳送給用戶端之前有兩次對要求執行動作的機會;在終端的中介軟體產生回應之前一次,而在終端的中介軟體產生回應之後再一次。

使用 app.Run() 新增的委派一律是終端的中介軟體。 它們不會呼叫管線中的下一個中介軟體。 它們是最後執行的中介軟體元件。 它們只需要一個 HttpContext 物件作為參數。 app.Run() 是新增終端中介軟體的捷徑。

請思考一下下列範例:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello from middleware 1. Passing to the next middleware!\r\n");

    // Call the next middleware in the pipeline
    await next.Invoke();

    await context.Response.WriteAsync("Hello from middleware 1 again!\r\n");
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from middleware 2!\r\n");
});

app.Run();

在上述程式碼中:

  • app.Use() 定義了一個中介軟體元件,其:
    • 將 "Hello from middleware 1. Passing to the next middleware!" 寫入回應中。
    • 將要求傳遞給管線中的下一個中介軟體元件,並使用 await next.Invoke() 等待其完成。
    • 在管線中的下一個元件完成後,它會寫入 "Hello from middleware 1 again!"
  • 第一個 app.Run() 定義了一個中介軟體元件,其將 "Hello from middleware 2!" 寫入回應中。
  • 第二個 app.Run() 會啟動應用程式。

在執行階段,當網頁瀏覽器將要求傳送至此應用程式時,中介軟體元件會按照它們被新增至管線的順序執行。 該應用程式會傳回以下回應:

Hello from middleware 1. Passing to the next middleware!
Hello from middleware 2!
Hello from middleware 1 again!

內建的中介軟體

ASP.NET Core 會提供一組內建的中介軟體元件,您可以使用它們來為您的應用程式新增常用的功能。 除了明確新增的中介軟體元件之外,依預設還會隱含地為您新增一些中介軟體。 例如,WebApplication.CreateBuilder() 會傳回一個 WebApplicationBuilder,用於新增開發人員例外狀況頁面路由中介軟體,如果設定了相關服務,則會有條件地新增驗證和授權中介軟體,並新增端點路由中介軟體。

例如,請考慮下列 Program.cs 檔案:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

在上述程式碼中:

  • app.UseExceptionHandler() 新增了一個攔截例外狀況並傳回錯誤頁面的中介軟體元件。
  • app.UseHsts() 新增了一個設定 Strict-Transport-Security 標頭的中介軟體元件。
  • app.UseHttpsRedirection() 新增了一個將 HTTP 要求重新導向到 HTTPS 的中介軟體元件。
  • app.UseAntiforgery() 新增了一個可防止跨網站偽造要求 (CSRF) 攻擊的中介軟體元件。
  • app.MapStaticAssets()app.MapRazorComponents<App>() 會將路由對應到端點,然後由端點路由中介軟體處理它們。 端點路由中介軟體會由 WebApplicationBuilder 隱含地新增。

根據應用程式的類型和您的需求,還有許多內建的中介軟體元件您可以在您的應用程式中使用。 請查看檔案以取得完整清單

提示

在此內容中,以 Use 開頭的方法通常用於對應中介軟體。 以 Map 開頭的方法通常用於對應端點。

重要

中介軟體元件新增到管線的順序很重要! 某些中介軟體元件必須先執行,其他元件才能正常運作。 請查看每個中介軟體元件的文件以確定正確的順序。