Chúng ta có thể cấu hình middleware trong phương thức Configure của lớp Startup sử dụng instance IApplicationBuilder.
Run() là extension method trên instance IApplicationBuilder thêm một terminal middleware vào request pipeline của ứng dụng.
Phương thức Run là extension method trên IApplicationBuilder và chấp nhận tham số kiểu RequestDelegate.
Signature của Run method
public static void Run(this IApplicationBuilder app, RequestDelegate handler)
Signature của RequestDelegate
public delegate Task RequestDelegate(HttpContext context);
Ví dụ Run()
public class Startup {
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
app.Run(async (context) => {
await context.Response.WriteAsync("Hello World!");
});
}
}
Hàm MyMiddleware ở trên không phải async và sẽ block thread cho đến khi hoàn thành. Nên làm nó async bằng async/await để cải thiện performance và scalability.
public class Startup {
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.Run(MyMiddleware);
}
private async Task MyMiddleware(HttpContext context) {
await context.Response.WriteAsync("Hello World!");
}
}
Cấu hình Multiple Middleware dùng Run()
Sau đây sẽ luôn thực thi Run method đầu tiên và không bao giờ đến Run method thứ hai:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.Run(async (context) => {
await context.Response.WriteAsync("1st Middleware");
});
// Đoạn dưới sẽ không bao giờ thực thi
app.Run(async (context) => {
await context.Response.WriteAsync("2nd Middleware");
});
}
USE()
Để cấu hình multiple middleware, dùng extension method Use(). Nó tương tự Run() trừ việc nó bao gồm tham số next để invoke middleware tiếp theo trong chuỗi.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.Use(async (context, next) => {
await context.Response.WriteAsync("1st Middleware!");
await next(); // Gọi middleware tiếp theo
});
app.Run(async (context) => {
await context.Response.WriteAsync("2nd Middleware");
});
}
So sánh chi tiết
| Đặc điểm | Use() | Run() |
|---|---|---|
| Tham số | HttpContext, Func<Task> next | HttpContext |
| Có thể gọi middleware tiếp theo | Có (qua next()) | Không (terminal) |
| Số lượng trong pipeline | Nhiều | Chỉ 1 (cuối cùng) |
| Use case | Middleware trung gian (logging, auth, v.v.) | Terminal middleware (trả về response cuối) |
Middleware Pipeline Pattern
public void Configure(IApplicationBuilder app) {
// Middleware 1: Logging
app.Use(async (context, next) => {
var start = DateTime.UtcNow;
await next();
var duration = DateTime.UtcNow - start;
Console.WriteLine($"Request took {duration.TotalMs}ms");
});
// Middleware 2: Authentication
app.UseAuthentication();
// Middleware 3: Authorization
app.UseAuthorization();
// Terminal middleware: MVC/Razor Pages
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}