มิดเดิลแวร์และตัวกรองใน Minimal APIs
เพิ่มการพิสูจน์ตัวตน การอนุญาต การจัดการข้อยกเว้น และตัวกรองจุดปลายทางลงในสายงานของ Minimal API
มิดเดิลแวร์และตัวกรองใน Minimal APIs เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
มิดเดิลแวร์กับตัวกรองจุดปลายทาง
ASP.NET Core มีชั้นการขยายระบบสองแบบ ได้แก่ มิดเดิลแวร์ (ครอบคลุมกระบวนการประมวลผลคำขอทั้งหมดและทำงานกับทุกคำขอ) และ ตัวกรองจุดปลายทาง (ทำงานเฉพาะกับจุดปลายทางบางรายการ) ทั้งสองแบบใช้กับ API แบบมินิมอลได้
การเพิ่มมิดเดิลแวร์ให้ API แบบมินิมอล
เพิ่มมิดเดิลแวร์มาตรฐานของ ASP.NET Core ด้วยเมธอด app.Use* ลำดับมีความสำคัญ เพราะมิดเดิลแวร์จะทำงานตามลำดับที่ลงทะเบียนไว้
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.MapGet("/secure", () => "Protected endpoint")
.RequireAuthorization();
app.Run();ตัวกรองจุดปลายทางแบบแทรกในบรรทัด
ตัวกรองจุดปลายทางทำงานคล้ายมิดเดิลแวร์ที่จำกัดขอบเขตไว้กับจุดปลายทางเดียว ใช้ AddEndpointFilter เพื่อเพิ่มตัวกรองในบรรทัดเดียว ตัวกรองสามารถตัดการทำงานต่อได้ด้วยการส่งคืนผลลัพธ์โดยไม่เรียกใช้ next
app.MapGet("/guarded", () => "Secret data")
.AddEndpointFilter(async (ctx, next) =>
{
var header = ctx.HttpContext.Request.Headers["X-Api-Key"];
if (header != "my-secret-key")
return Results.Unauthorized();
return await next(ctx); // proceed to handler
});ตัวกรองจุดปลายทางแบบใช้คลาส
ใช้อินเทอร์เฟซ IEndpointFilter เพื่อสร้างตัวกรองที่นำกลับมาใช้ซ้ำได้ ตัวกรองเหล่านี้ใช้กับจุดปลายทางแต่ละรายการหรือกลุ่มเส้นทางทั้งหมดได้
public class LoggingFilter : IEndpointFilter
{
private readonly ILogger<LoggingFilter> _logger;
public LoggingFilter(ILogger<LoggingFilter> logger) => _logger = logger;
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext ctx,
EndpointFilterDelegate next)
{
_logger.LogInformation("Before: {Path}", ctx.HttpContext.Request.Path);
var result = await next(ctx);
_logger.LogInformation("After: {Path}", ctx.HttpContext.Request.Path);
return result;
}
}
// Apply to a group
app.MapGroup("/api").AddEndpointFilter<LoggingFilter>();มิดเดิลแวร์สำหรับจัดการข้อยกเว้น
ใช้ app.UseExceptionHandler หรือมิดเดิลแวร์ ProblemDetails ในตัวเพื่อดักจับข้อยกเว้นที่ไม่ได้จัดการ และส่งคืนการตอบกลับปัญหาตาม RFC 7807
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
// OR for custom logic:
app.UseExceptionHandler(errApp =>
errApp.Run(async ctx =>
{
var ex = ctx.Features.Get<IExceptionHandlerFeature>()?.Error;
ctx.Response.StatusCode = 500;
await ctx.Response.WriteAsJsonAsync(new { error = ex?.Message });
}));มิดเดิลแวร์แบบตัดจบ
ใช้ app.MapShortCircuit() (.NET 8 ขึ้นไป) หรือ Results.StatusCode() ในตัวกรอง เพื่อส่งคืนการตอบกลับทันทีโดยไม่เรียกใช้กระบวนการประมวลผลคำขอทั้งหมด
// Block known bad bots at the edge
app.MapGet("/robots.txt", () => "User-agent: *\nDisallow: /")
.ShortCircuit(); // .NET 8: returns response immediately
// Or in a filter:
app.MapGet("/maintenance", () => "OK")
.AddEndpointFilter((ctx, next) =>
ValueTask.FromResult<object?>(Results.StatusCode(503)));การจำกัดอัตราใน .NET 7 ขึ้นไป
มิดเดิลแวร์จำกัดอัตราในตัวช่วยป้องกันจุดปลายทางจากการใช้งานในทางที่ผิด ใช้นโยบายกับทั้งระบบหรือกับจุดปลายทางแต่ละรายการด้วย RequireRateLimiting()
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(opt =>
{
opt.AddFixedWindowLimiter("fixed", o =>
{
o.PermitLimit = 10;
o.Window = TimeSpan.FromSeconds(10);
o.QueueLimit = 0;
o.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
opt.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});
app.UseRateLimiter();
app.MapGet("/search", Search).RequireRateLimiting("fixed");การกำหนดค่า CORS
กำหนดค่านโยบาย CORS ในบริการ แล้วนำไปใช้กับทั้งระบบหรือจุดปลายทางแต่ละรายการ เพื่อควบคุมว่าแหล่งที่มาใดบ้างที่เข้าถึง API ของคุณได้
builder.Services.AddCors(opt =>
opt.AddPolicy("AllowFrontend", policy =>
policy.WithOrigins("https://myapp.com")
.AllowAnyHeader()
.AllowAnyMethod()));
app.UseCors("AllowFrontend");
// Or per endpoint:
app.MapGet("/public-data", () => "data")
.RequireCors("AllowFrontend");มิดเดิลแวร์แคชผลลัพธ์
AddOutputCache จะแคชการตอบกลับไว้บนเซิร์ฟเวอร์ นำไปใช้กับจุดปลายทางที่ต้องการเพื่อส่งการตอบกลับจากแคช โดยไม่ต้องเข้าถึงฐานข้อมูลในทุกคำขอ
builder.Services.AddOutputCache();
app.UseOutputCache();
app.MapGet("/products", async (AppDbContext db) =>
Results.Ok(await db.Products.AsNoTracking().ToListAsync()))
.CacheOutput(p => p.Expire(TimeSpan.FromMinutes(5)));ลำดับและการเชื่อมตัวกรอง
ตัวกรองจะทำงานตามลำดับที่เพิ่มเข้ามา (ตัวกรองชั้นนอกสุดก่อน และชั้นในสุดทีหลัง เช่นเดียวกับมิดเดิลแวร์) คุณสามารถเชื่อมตัวกรองหลายรายการเข้ากับจุดปลายทางหรือกลุ่มเดียวกันได้
app.MapPost("/orders", CreateOrder)
.AddEndpointFilter<LoggingFilter>() // runs first
.AddEndpointFilter<ValidationFilter>() // runs second
.AddEndpointFilter<AuthFilter>() // runs third
.RequireAuthorization(); // JWT checked by middlewareตัวอย่างจากโลกจริง: มิดเดิลแวร์คีย์ API
มิดเดิลแวร์คีย์ API ที่นำกลับมาใช้ซ้ำได้ ซึ่งอ่านคีย์จากส่วนหัวและตัดการทำงานต่อพร้อมส่งคืน 401 หากคีย์ไม่ถูกต้อง
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly string _expectedKey;
public ApiKeyMiddleware(RequestDelegate next, IConfiguration cfg)
{
_next = next;
_expectedKey = cfg["ApiKey"] ?? throw new Exception("ApiKey not configured");
}
public async Task InvokeAsync(HttpContext ctx)
{
if (!ctx.Request.Headers.TryGetValue("X-Api-Key", out var key)
|| key != _expectedKey)
{
ctx.Response.StatusCode = 401;
await ctx.Response.WriteAsync("Invalid API key");
return;
}
await _next(ctx);
}
}
app.UseMiddleware<ApiKeyMiddleware>();ตรวจสอบความเข้าใจ
ความแตกต่างสำคัญระหว่างมิดเดิลแวร์กับตัวกรองจุดปลายทางใน API แบบมินิมอลคืออะไร
สรุป: มิดเดิลแวร์และตัวกรอง
ประเด็นสำคัญ:
- มิดเดิลแวร์ (UseX) ทำงานกับทุกคำขอทั่วทั้งระบบตามลำดับในกระบวนการประมวลผลคำขอ
- ตัวกรองจุดปลายทาง (AddEndpointFilter) จำกัดขอบเขตไว้กับจุดปลายทางหรือกลุ่มที่ระบุ
- ใช้อินเทอร์เฟซ IEndpointFilter เพื่อสร้างคลาสตัวกรองที่นำกลับมาใช้ซ้ำได้และรองรับ DI
- มิดเดิลแวร์ในตัว ได้แก่ การจำกัดอัตรา CORS การแคชผลลัพธ์ และการจัดการข้อยกเว้น
- ลำดับตัวกรองมีความสำคัญ เพราะตัวกรองซ้อนกันเหมือนมิดเดิลแวร์ (เพิ่มก่อน = อยู่ชั้นนอกสุด)
เรียนรู้ C# ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 93
- บทเรียน
- 346
คำถามที่พบบ่อย
บทเรียน “มิดเดิลแวร์และตัวกรองใน Minimal APIs” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “มิดเดิลแวร์และตัวกรองใน Minimal APIs” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “มิดเดิลแวร์และตัวกรองใน Minimal APIs”
เพิ่มการพิสูจน์ตัวตน การอนุญาต การจัดการข้อยกเว้น และตัวกรองจุดปลายทางลงในสายงานของ Minimal API คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “มิดเดิลแวร์และตัวกรองใน Minimal APIs” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้าง Minimal API แรกของคุณ
- กลุ่มเส้นทาง พารามิเตอร์ และการตรวจสอบ
- มิดเดิลแวร์และตัวกรองใน Minimal APIs
- OpenAPI การกำหนดเวอร์ชัน และการนำไปใช้งาน