C# Academy · บทเรียน

มิดเดิลแวร์และตัวกรองใน Minimal APIs

เพิ่มการพิสูจน์ตัวตน การอนุญาต การจัดการข้อยกเว้น และตัวกรองจุดปลายทางลงในสายงานของ Minimal API

บทเรียน 3 จาก 413 ขั้นตอน

มิดเดิลแวร์และตัวกรองใน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้าง Minimal API แรกของคุณ
  2. กลุ่มเส้นทาง พารามิเตอร์ และการตรวจสอบ
  3. มิดเดิลแวร์และตัวกรองใน Minimal APIs
  4. OpenAPI การกำหนดเวอร์ชัน และการนำไปใช้งาน
← กลับไปที่ C# Academy