การตัดการทำงานระยะสั้นและการแตกแขนง
ใช้ MapWhen, UseWhen และมิดเดิลแวร์ปลายทางเพื่อแตกแขนงหรือยุติสายงานตามเงื่อนไขของคำขอ
การตัดการทำงานระยะสั้นและการแตกแขนง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
การแยกแขนงและการหยุดก่อนถึงส่วนถัดไป
ไม่ใช่ทุกคำขอที่ควรผ่านไปป์ไลน์มิดเดิลแวร์ทั้งหมด ASP.NET Core จึงมีเครื่องมือสำหรับแยกแขนง (ส่งชุดคำขอย่อยไปยังไปป์ไลน์ที่แตกต่างกัน) และหยุดก่อนถึงส่วนถัดไป (หยุดประมวลผลแล้วส่งกลับทันที)
Map: การแยกแขนงถาวรตามเส้นทาง
Map สร้างแขนงถาวร คำขอที่ตรงกับคำนำหน้าจะเข้าสู่แขนงนั้นและจะไม่กลับมายังไปป์ไลน์หลัก
app.Map("/api", apiApp =>
{
apiApp.UseAuthentication();
apiApp.UseAuthorization();
apiApp.Run(async ctx =>
await ctx.Response.WriteAsync("API branch"));
});
// Requests to /api/... enter the branch above.
// Requests to /public/... skip the branch entirely.
app.Run(async ctx =>
await ctx.Response.WriteAsync("Main pipeline"));MapWhen: การแยกแขนงตามเงื่อนไข
MapWhen แยกแขนงตามเงื่อนไขใดก็ได้ เช่น ส่วนหัว พารามิเตอร์คำค้น หรือตรรกะที่กำหนดเอง เช่นเดียวกับ Map แขนงนี้จะแยกออกอย่างถาวรและจะไม่กลับมารวมกับไปป์ไลน์หลัก
// Branch when a specific header is present
app.MapWhen(
ctx => ctx.Request.Headers.ContainsKey("X-Internal"),
internalApp =>
{
internalApp.UseMiddleware<InternalApiMiddleware>();
internalApp.Run(async ctx =>
await ctx.Response.WriteAsync("Internal route"));
});
// Branch on query parameter
app.MapWhen(
ctx => ctx.Request.Query.ContainsKey("legacy"),
legacyApp => legacyApp.UseMiddleware<LegacyHandlerMiddleware>());UseWhen: การแยกแขนงแบบมีเงื่อนไขที่กลับมารวมกัน
UseWhen คล้ายกับ MapWhen แต่แขนงจะกลับมารวมกับไปป์ไลน์หลักหลังจากทำงานเสร็จ ทำให้คุณสามารถเพิ่มมิดเดิลแวร์ตามเงื่อนไขได้โดยไม่ต้องแยกไปป์ไลน์ออกจากกัน
// Log only for authenticated API calls; public routes not logged
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api")
&& ctx.User.Identity?.IsAuthenticated == true,
loggedApp =>
{
loggedApp.UseMiddleware<AuditMiddleware>();
});
// All requests continue here after the branch
app.UseRouting();
app.MapControllers();การหยุดไปป์ไลน์ด้วยการไม่เรียกส่วนถัดไป
มิดเดิลแวร์ใด ๆ ก็สามารถหยุดไปป์ไลน์ก่อนถึงส่วนถัดไปได้ด้วยการเขียนการตอบกลับและไม่เรียกใช้ next ไปป์ไลน์จะหยุดที่จุดนั้น และการตอบกลับจะถูกส่งคืนให้ไคลเอนต์
app.Use(async (ctx, next) =>
{
// IP allowlist check
var ip = ctx.Connection.RemoteIpAddress?.ToString();
var allowed = new[] { "127.0.0.1", "::1", "10.0.0.0/8" };
if (!IsAllowed(ip, allowed))
{
ctx.Response.StatusCode = 403;
await ctx.Response.WriteAsJsonAsync(
new { error = "Access denied from this IP" });
return; // short-circuit
}
await next(ctx); // proceed
});ShortCircuit() ใน .NET 8
ใน .NET 8 MapShortCircuit และส่วนขยาย ShortCircuit() บนจุดปลายทางจะมอบเส้นทางการหยุดก่อนถึงส่วนถัดไปแบบประกาศที่ปรับให้เหมาะสมอย่างมาก
// Reject known bad paths immediately — skip entire pipeline
app.MapShortCircuit(404, "robots.txt", "favicon.ico");
// Or on a specific endpoint:
app.MapGet("/health", () => "OK")
.ShortCircuit(); // skips auth, rate limiting, etc.
// 'Run' middleware also short-circuits:
app.Map("/old-api", old =>
old.Run(ctx =>
{
ctx.Response.StatusCode = 301;
ctx.Response.Headers.Location = "/api/v2";
return Task.CompletedTask;
}));มิดเดิลแวร์สิ้นสุดเทียบกับการกำหนดเส้นทางจุดปลายทาง
ก่อน .NET 3 app.Run() เป็นตัวเลือกเดียวสำหรับการสิ้นสุด ปัจจุบันนิยมใช้การกำหนดเส้นทางจุดปลายทาง (MapGet, MapControllers) มากกว่า เพราะทำงานร่วมกับการอนุญาตสิทธิ์ การจำกัดอัตรา และเมทาดาทา
// OLD: terminal middleware
app.Run(async ctx => {
if (ctx.Request.Path == "/ping")
await ctx.Response.WriteAsync("pong");
});
// PREFERRED: endpoint routing
app.MapGet("/ping", () => "pong")
.WithTags("Health")
.AllowAnonymous()
.RequireRateLimiting("basic");รายละเอียดการจับคู่เส้นทาง
Map("/api") จะจับคู่กับ /api และ /api/anything เส้นทางที่จับคู่แล้วจะถูกนำออกจาก Request.Path ภายในแขนง และย้ายไปเก็บไว้ใน Request.PathBase
app.Map("/api", apiApp =>
{
apiApp.Use(async (ctx, next) =>
{
// Path in branch: /users/42 (prefix removed)
Console.WriteLine(ctx.Request.Path); // /users/42
Console.WriteLine(ctx.Request.PathBase); // /api
await next(ctx);
});
apiApp.MapGet("/users/{id}", (int id) => id);
});การผสานรูปแบบการแยกแขนง
แอปจริงจะผสาน Map, UseWhen และการหยุดก่อนถึงส่วนถัดไปเพื่อสร้างไปป์ไลน์หลายชั้น: เส้นทางสาธารณะมีการประมวลผลแบบเบา เส้นทาง API มีการยืนยันตัวตน และเส้นทางผู้ดูแลระบบมีการตรวจสอบเพิ่มเติม
// Public area — no auth
app.Map("/public", pub =>
{
pub.MapGet("/health", () => "OK");
pub.MapGet("/docs", () => "Documentation");
});
// API area — full auth + rate limiting
app.Map("/api", api =>
{
api.UseAuthentication();
api.UseAuthorization();
api.UseRateLimiter();
api.MapControllers();
});
// Admin area — require admin role
app.Map("/admin", admin =>
{
admin.UseAuthentication();
admin.UseAuthorization();
admin.MapControllers().RequireAuthorization("AdminPolicy");
});กรณีใช้งานจริง: มิดเดิลแวร์ทดสอบแบบ A/B
มิดเดิลแวร์ทดสอบแบบ A/B จะแยกคำขอไปยังตัวจัดการที่แตกต่างกันตามคุกกี้หรือส่วนหัว โดยไม่ต้องแก้ไขโค้ดจุดปลายทาง
app.UseWhen(
ctx => ctx.Request.Cookies.TryGetValue("ab-group", out var g) && g == "B",
betaApp =>
{
betaApp.Use(async (ctx, next) =>
{
ctx.Items["IsGroupB"] = true;
await next(ctx);
});
});
// Endpoint reads the flag:
app.MapGet("/products", (HttpContext ctx, ProductService svc) =>
{
bool isB = ctx.Items.ContainsKey("IsGroupB");
return isB ? svc.GetNewLayoutAsync() : svc.GetOldLayoutAsync();
});ตรวจสอบความเข้าใจ
ความแตกต่างที่สำคัญระหว่าง MapWhen และ UseWhen คืออะไร
สรุป: การหยุดก่อนถึงส่วนถัดไปและการแยกแขนง
ประเด็นสำคัญ:
Map: แขนงถาวรตามเส้นทาง (ไม่กลับมารวมกัน)MapWhen: แขนงถาวรตามเงื่อนไขUseWhen: แขนงแบบมีเงื่อนไขที่กลับมารวมกับไปป์ไลน์หลัก- การหยุดก่อนถึงส่วนถัดไป: ไม่เรียกใช้
nextเขียนการตอบกลับแล้วส่งคืน ShortCircuit()(.NET 8): จุดปลายทางสิ้นสุดแบบประกาศที่ปรับให้เหมาะสม- ผสานการแยกแขนงเพื่อสร้างไปป์ไลน์หลายชั้น: สาธารณะ / API / ผู้ดูแลระบบ
คำถามที่พบบ่อย
บทเรียน “การตัดการทำงานระยะสั้นและการแตกแขนง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตัดการทำงานระยะสั้นและการแตกแขนง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การตัดการทำงานระยะสั้นและการแตกแขนง”
ใช้ MapWhen, UseWhen และมิดเดิลแวร์ปลายทางเพื่อแตกแขนงหรือยุติสายงานตามเงื่อนไขของคำขอ คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การตัดการทำงานระยะสั้นและการแตกแขนง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ภาพรวมสายงาน ASP.NET Core
- การเขียนมิดเดิลแวร์แบบกำหนดเอง
- การตัดการทำงานระยะสั้นและการแตกแขนง
- ลำดับมิดเดิลแวร์และมิดเดิลแวร์ในตัว