แบบฝึกหัด - สร้างตรงกลางแบบกําหนดเอง
นักพัฒนาสามารถสร้างคอมโพเนนต์ของ middleware แบบกําหนดเองเพื่อเพิ่มฟังก์ชันการทํางานให้กับแอป ASP.NET Core สามารถแทรกตรงกลางแบบกําหนดเองได้ทุกที่ในไปป์ไลน์กึ่งกลาง และสามารถใช้ได้กับส่วนประกอบของ middleware ในตัวตามที่เห็นในตัวอย่างนี้:
ทีมการปฏิบัติงานเครือข่ายของบริษัทของคุณคือการแก้ไขปัญหาประสิทธิภาพการทํางานในสภาพแวดล้อมการผลิต ทีมของคุณนํามอบหมายให้คุณใช้ฟีเจอร์บางอย่างเพื่อสนับสนุนการตรวจสอบแบบเรียลไทม์ของแอปได้ดียิ่งขึ้น แอปควรบันทึกรายละเอียดคําขอไปยังคอนโซล สําหรับคําขอแต่ละรายการ ควรบันทึกเมธอดคําขอ เส้นทาง และรหัสสถานะการตอบสนอง
ในแบบฝึกหัดนี้ คุณจะสร้างคอมโพเนนต์ middleware แบบกําหนดเองที่บันทึกการร้องขอรายละเอียดไปยังคอนโซล
เพิ่มตรงกลางแบบกําหนดเอง
ลองปรับเปลี่ยนแอป ASP.NET Core ที่มีอยู่เพื่อรวมตรงกลางแบบกําหนดเองซึ่งบันทึกรายละเอียดคําขอไปยังคอนโซล
เปิดไฟล์ Program.cs ถ้ายังไม่ได้เปิด
ทันทีก่อน
app.Run()ให้แทรกโค้ดต่อไปนี้:app.Use(async (context, next) => { Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}"); await next(); });ในโค้ดก่อนหน้า:
-
app.Use()เพิ่มคอมโพเนนต์ตรงกลางแบบกําหนดเองให้กับไปป์ไลน์ คอมโพเนนต์จะใช้วัตถุHttpContextและวัตถุRequestDelegateเป็นพารามิเตอร์ - ผู้รับมอบสิทธิ์เขียนวิธีการร้องขอ เส้นทาง และรหัสสถานะการตอบกลับไปยังคอนโซล
-
await next()เรียกใช้คอมโพเนนต์ middleware ถัดไปในไปป์ไลน์
-
ทดสอบการเปลี่ยนแปลง
กด Ctrl+Shift+F5 เพื่อสร้างและเริ่มแอปใหม่
เมื่อหน้าต่างเบราว์เซอร์เปิดขึ้น ให้สังเกตว่า URL รากแสดง "ยินดีต้อนรับสู่ Contoso!"
เพิ่ม
/historyลงใน URL และกด Enter เบราว์เซอร์จะเปลี่ยนเส้นทางไปยังหน้า/aboutใน Visual Studio Code กด Ctrl+Shift+P เพื่อเปิดชุดแบบสีคําสั่ง ค้นหาและเลือก Debug Console: มุ่งเน้นไปที่มุมมองคอนโซลดีบัก เพื่อสลับไปยังแท็บ ดีบักคอนโซล ในบานหน้าต่างด้านล่าง โปรดสังเกตบรรทัดต่อไปนี้:
GET / 200 GET /about 200เอาต์พุตคอนโซลแสดงเมธอดคําขอ เส้นทาง และรหัสสถานะการตอบสนองสําหรับแต่ละคําขอ บรรทัดแรกแสดงคําขอสําหรับ URL ราก และบรรทัดที่สองแสดงคําขอสําหรับหน้า
/aboutโน้ต
นอกจากนี้เบราว์เซอร์ของคุณอาจร้องขอ
/favicon.icoนี่เป็นคําขอมาตรฐานสําหรับ favicon ของเว็บไซต์และสามารถเพิกเฉยได้ปล่อยให้แอปทํางานสําหรับแบบฝึกหัดถัดไป
เปลี่ยนลําดับของโปรแกรมตรงกลาง
แอปดูเหมือนจะทํางาน แต่มีปัญหา คุณร้องขอหน้า /history แต่เอาต์พุตคอนโซลไม่แสดง ลักษณะการทํางานนี้เกิดขึ้นเนื่องจากคอมโพเนนต์ middleware แบบกําหนดเองที่บันทึกการร้องขอรายละเอียดถูกเพิ่มหลังจากเขียน URL แบบตรงกลางอีกครั้ง เขียน URL ใหม่สําหรับการร้องขอการเปลี่ยนเส้นทางจาก /history ไปยัง /about และส่งการตอบกลับ และคอมโพเนนต์ตรงกลางแบบกําหนดเองไม่เห็นคําขอ มาแก้ไขปัญหานี้
ย้ายเส้น
app.Use()ที่คุณเพิ่มไปยังทันทีก่อนบรรทัดapp.UseRewriter()ไฟล์ Program.cs แบบเต็มควรมีลักษณะดังนี้:
using Microsoft.AspNetCore.Rewrite; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Use(async (context, next) => { Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}"); await next(); }); app.UseRewriter(new RewriteOptions().AddRedirect("history", "about")); app.MapGet("/", () => "Hello World!"); app.MapGet("/about", () => "Contoso was founded in 2000."); app.Run();ในตอนนี้คอมโพเนนต์ของ middleware แบบกําหนดเองจะถูกเพิ่มก่อนเขียน URL แบบตรงกลางอีกครั้ง คอมโพเนนต์ middleware แบบกําหนดเองจะบันทึกรายละเอียดคําขอก่อนที่ตัวเขียน URL แบบตรงกลางจะประมวลผลคําขอและเปลี่ยนเส้นทาง
รีสตาร์ทแอปอีกครั้งและทดสอบเหมือนก่อนหน้านี้ ในตอนนี้ ดีบักคอนโซล เอาต์พุตควรมีคําขอสําหรับหน้า
/historyGET / 200 GET /history 200 GET /about 200เอาต์พุตคอนโซลจะแสดงคําขอสําหรับหน้า
/historyก่อนที่จะเปลี่ยนเส้นทางไปยังหน้า/about
แก้ไขรหัสสถานะ
แอปใกล้จะพร้อมแล้ว แต่ยังมีอีกหนึ่งปัญหา รหัสสถานะในเอาต์พุตของคอนโซลมักจะเป็น 200 แม้ว่าแอปจะเปลี่ยนเส้นทางคําขอก็ตาม รหัสสถานะสําหรับคําขอ /history ควรเป็นการเปลี่ยนเส้นทาง 302 เหตุผลสําหรับลักษณะการทํางานนี้คือปัญหาลําดับอื่นที่มีการประมวลผลคอมโพเนนต์ของมิดเดิลแวร์
คอมโพเนนต์ middleware แบบกําหนดเองจะบันทึกรายละเอียดไปยังคอนโซล จากนั้นเรียกใช้ await next() เพื่อส่งผ่านไปยังคอมโพเนนต์ middleware ถัดไป ปัญหาคือ คุณสมบัติ StatusCode ของวัตถุ Response ถูกตั้งค่าหลังจากที่คอมโพเนนต์ของเครื่องอ่านตรงกลางเทอร์มินัลเริ่มต้นการตอบสนอง ลองเปลี่ยนรหัสเพื่อแก้ไขปัญหานี้
ในผู้รับมอบสิทธิ์ที่คุณเพิ่ม ย้ายบรรทัด
Console.WriteLine()ไปหลังจากบรรทัดawait next()โค้ดที่อัปเดตแล้วควรมีลักษณะดังนี้:
app.Use(async (context, next) => { await next(); Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}"); });ในตอนนี้ คอมโพเนนต์ middleware แบบกําหนดเองจะบันทึกรายละเอียดคําขอหลังจากที่คอมโพเนนต์ middleware เทอร์มินัลตั้งค่ารหัสสถานะการตอบสนอง
รีสตาร์ทและทดสอบคําขอ
/historyอีกครั้ง เอาต์พุตคอนโซลดีบัก ตอนนี้ควรแสดงรหัสสถานะที่ถูกต้องGET / 200 GET /history 302 GET /about 200