.NET 6版本中間件的使用
.NET 6版本中間件的使用
中間件是一種處理HTTP請求和響應的可重用組件,通常用于添加處理邏輯或修改請求和響應。本文將演示如何創建.NET 6版本的中間件。
創建中間件
讓我們從創建一個簡單的中間件類開始。我們將打印請求的URL,然后調用下一個中間件:
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine($"[MyMiddleware] URL: {context.Request.Path}");
await _next(context);
}
}
在上面的代碼中,我們定義了一個MyMiddleware類,它實現了InvokeAsync方法。在這個方法中,我們打印了請求的URL,并調用下一個中間件。
注冊中間件
在.NET 6中,注冊中間件的方式也類似于.NET 5。我們可以將我們的中間件添加到應用程序的請求處理管道中。
builder.UseMiddleware<MyMiddleware>();
請注意,上面的代碼應該在app.UseRouting()之后調用,但在app.UseEndpoints()之前。
完整的Program.cs文件如下所示:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseMiddleware<MyMiddleware>();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run();
在上面的代碼中,我們將MyMiddleware添加到了請求處理管道中。然后我們添加了一些其他的中間件,例如HTTPS重定向和靜態文件服務。
測試中間件
現在我們已經完成了自己的中間件,我們來測試它。
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
...
})
.ToArray();
}
}
上面的代碼中,我們創建了一個簡單的WeatherForecastController,其中有一個Get()操作。我們將在這個操作中測試我們的中間件。
通過調用Swagger UI來測試應用程序:
- 在瀏覽器中導航到
https://{your_host}/swagger/index.html。 - 選擇“GET WeatherForecast”操作,然后單擊“Try it out”按鈕。
- 單擊“Execute”按鈕。
您應該看到控制臺輸出我們的自定義中間件的URL:
[MyMiddleware] URL: /WeatherForecast
中間件的順序
在注冊多個中間件時,它們的順序非常重要。請求將從第一個中間件開始處理,然后逐個傳遞到下一個中間件,直到到達最后一個中間件,然后響應將根據這些中間件的順序返回。在.NET 6中,您可以通過調用 UseMiddleware<T> 或 UseMiddleware 方法添加多個中間件。
例如,讓我們創建一個新的中間件類,以便我們可以測試中間件的順序:
public class MySecondMiddleware
{
private readonly RequestDelegate _next;
public MySecondMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine("[MySecondMiddleware] Start");
await _next(context);
Console.WriteLine("[MySecondMiddleware] End");
}
}
在上面的代碼中,我們定義了一個名為MySecondMiddleware的新中間件類,它與MyMiddleware類非常相似。它在請求處理管道的開頭打印了消息,然后在請求處理管道的結尾打印了另一個消息。
現在,我們可以將兩個中間件添加到應用程序中:
app.UseMiddleware<MyMiddleware>();
app.UseMiddleware<MySecondMiddleware>();
您應該注意到,我們添加了 MyMiddleware 和 MySecondMiddleware 中間件,它們的順序是有意義的,因為它們將按照注冊的順序依次處理請求。
如果我們在測試控制器方法時,您會看到控制臺輸出,它顯示請求和響應在兩個中間件中傳遞。輸出如下:
[MyMiddleware] URL: /WeatherForecast
[MySecondMiddleware] Start
[MySecondMiddleware] End
您可以看到,請求通過了 MyMiddleware 中間件,然后通過 MySecondMiddleware 中間件。注意消息的順序是相反的,因為我們將它們注冊成了相反的順序。
控制中間件的流程
在.NET 6中,我們可以通過終止請求來控制中間件流程。如果我們需要在請求處理管道中停止中間件的處理過程,則可以使用 HttpContext.Abort() 方法。
例如,讓我們為我們的控制器方法添加一些邏輯,并在中間件中檢查該邏輯。如果條件不滿足,我們將終止請求處理過程。
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult Get(int id)
{
if (id < 1 || id > 5)
{
return BadRequest("Invalid ID");
}
return Ok(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
...
}).ToArray());
}
}
在上面的代碼中,我們更改了 Get() 操作以檢查傳遞的 id 值。如果 id 不在1到5的范圍內,則返回400響應。
現在,讓我們在 MyMiddleware 中間件中添加一些邏輯,以檢查請求是否是有效請求。
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine($"[MyMiddleware] URL: {context.Request.Path}");
if (context.Request.Path == "/WeatherForecast/2")
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
await context.Response.WriteAsync("Resource not found");
return;
}
await _next(context);
}
}
在上面的代碼中,我們添加了一個檢查,如果URL是 /WeatherForecast/2,則返回404響應并終止請求處理過程。
現在,當我們通過查找 /WeatherForecast/2 在瀏覽器中測試應用程序時,我們應該收到 Resource not found 響應。并且應用程序將在 MyMiddleware 中間件中止請求處理過程。
總結:
在本文中,我們演示了如何在.NET 6中創建和使用中間件,并介紹了如何控制中間件的順序。中間件是.NET Web應用程序中非常有用的組件,它允許我們輕松地處理請求和響應。注意中間件的注冊順序是非常重要的,尤其是在使用多個中間件的情況下。我們還演示了如何將自定義邏輯添加到控制器方法中,并在中間件中檢查該邏輯。中間件是.NET Web應用程序非常有用的組件,并且.NET 6為中間件的處理帶來了更多的靈活性。

浙公網安備 33010602011771號