แบบฝึกหัด - สร้างตรงกลางแบบกําหนดเอง

เสร็จสมบูรณ์เมื่อ

นักพัฒนาสามารถสร้างคอมโพเนนต์ของ middleware แบบกําหนดเองเพื่อเพิ่มฟังก์ชันการทํางานให้กับแอป ASP.NET Core สามารถแทรกตรงกลางแบบกําหนดเองได้ทุกที่ในไปป์ไลน์กึ่งกลาง และสามารถใช้ได้กับส่วนประกอบของ middleware ในตัวตามที่เห็นในตัวอย่างนี้:

ไดอะแกรมที่แสดงโฟลว์ของคําขอผ่านไปป์ไลน์

ทีมการปฏิบัติงานเครือข่ายของบริษัทของคุณคือการแก้ไขปัญหาประสิทธิภาพการทํางานในสภาพแวดล้อมการผลิต ทีมของคุณนํามอบหมายให้คุณใช้ฟีเจอร์บางอย่างเพื่อสนับสนุนการตรวจสอบแบบเรียลไทม์ของแอปได้ดียิ่งขึ้น แอปควรบันทึกรายละเอียดคําขอไปยังคอนโซล สําหรับคําขอแต่ละรายการ ควรบันทึกเมธอดคําขอ เส้นทาง และรหัสสถานะการตอบสนอง

ในแบบฝึกหัดนี้ คุณจะสร้างคอมโพเนนต์ middleware แบบกําหนดเองที่บันทึกการร้องขอรายละเอียดไปยังคอนโซล

เพิ่มตรงกลางแบบกําหนดเอง

ลองปรับเปลี่ยนแอป ASP.NET Core ที่มีอยู่เพื่อรวมตรงกลางแบบกําหนดเองซึ่งบันทึกรายละเอียดคําขอไปยังคอนโซล

  1. เปิดไฟล์ Program.cs ถ้ายังไม่ได้เปิด

  2. ทันทีก่อน 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 ถัดไปในไปป์ไลน์

ทดสอบการเปลี่ยนแปลง

  1. กด Ctrl+Shift+F5 เพื่อสร้างและเริ่มแอปใหม่

  2. เมื่อหน้าต่างเบราว์เซอร์เปิดขึ้น ให้สังเกตว่า URL รากแสดง "ยินดีต้อนรับสู่ Contoso!"

  3. เพิ่ม /history ลงใน URL และกด Enter เบราว์เซอร์จะเปลี่ยนเส้นทางไปยังหน้า /about

  4. ใน Visual Studio Code กด Ctrl+Shift+P เพื่อเปิดชุดแบบสีคําสั่ง ค้นหาและเลือก Debug Console: มุ่งเน้นไปที่มุมมองคอนโซลดีบัก เพื่อสลับไปยังแท็บ ดีบักคอนโซล ในบานหน้าต่างด้านล่าง โปรดสังเกตบรรทัดต่อไปนี้:

    GET / 200
    GET /about 200
    

    เอาต์พุตคอนโซลแสดงเมธอดคําขอ เส้นทาง และรหัสสถานะการตอบสนองสําหรับแต่ละคําขอ บรรทัดแรกแสดงคําขอสําหรับ URL ราก และบรรทัดที่สองแสดงคําขอสําหรับหน้า /about

    โน้ต

    นอกจากนี้เบราว์เซอร์ของคุณอาจร้องขอ /favicon.ico นี่เป็นคําขอมาตรฐานสําหรับ favicon ของเว็บไซต์และสามารถเพิกเฉยได้

  5. ปล่อยให้แอปทํางานสําหรับแบบฝึกหัดถัดไป

เปลี่ยนลําดับของโปรแกรมตรงกลาง

แอปดูเหมือนจะทํางาน แต่มีปัญหา คุณร้องขอหน้า /history แต่เอาต์พุตคอนโซลไม่แสดง ลักษณะการทํางานนี้เกิดขึ้นเนื่องจากคอมโพเนนต์ middleware แบบกําหนดเองที่บันทึกการร้องขอรายละเอียดถูกเพิ่มหลังจากเขียน URL แบบตรงกลางอีกครั้ง เขียน URL ใหม่สําหรับการร้องขอการเปลี่ยนเส้นทางจาก /history ไปยัง /about และส่งการตอบกลับ และคอมโพเนนต์ตรงกลางแบบกําหนดเองไม่เห็นคําขอ มาแก้ไขปัญหานี้

  1. ย้ายเส้น 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 แบบตรงกลางจะประมวลผลคําขอและเปลี่ยนเส้นทาง

  2. รีสตาร์ทแอปอีกครั้งและทดสอบเหมือนก่อนหน้านี้ ในตอนนี้ ดีบักคอนโซล เอาต์พุตควรมีคําขอสําหรับหน้า /history

    GET / 200
    GET /history 200
    GET /about 200
    

    เอาต์พุตคอนโซลจะแสดงคําขอสําหรับหน้า /history ก่อนที่จะเปลี่ยนเส้นทางไปยังหน้า /about

แก้ไขรหัสสถานะ

แอปใกล้จะพร้อมแล้ว แต่ยังมีอีกหนึ่งปัญหา รหัสสถานะในเอาต์พุตของคอนโซลมักจะเป็น 200 แม้ว่าแอปจะเปลี่ยนเส้นทางคําขอก็ตาม รหัสสถานะสําหรับคําขอ /history ควรเป็นการเปลี่ยนเส้นทาง 302 เหตุผลสําหรับลักษณะการทํางานนี้คือปัญหาลําดับอื่นที่มีการประมวลผลคอมโพเนนต์ของมิดเดิลแวร์

คอมโพเนนต์ middleware แบบกําหนดเองจะบันทึกรายละเอียดไปยังคอนโซล จากนั้นเรียกใช้ await next() เพื่อส่งผ่านไปยังคอมโพเนนต์ middleware ถัดไป ปัญหาคือ คุณสมบัติ StatusCode ของวัตถุ Response ถูกตั้งค่าหลังจากที่คอมโพเนนต์ของเครื่องอ่านตรงกลางเทอร์มินัลเริ่มต้นการตอบสนอง ลองเปลี่ยนรหัสเพื่อแก้ไขปัญหานี้

  1. ในผู้รับมอบสิทธิ์ที่คุณเพิ่ม ย้ายบรรทัด Console.WriteLine() ไปหลังจากบรรทัด await next()

    โค้ดที่อัปเดตแล้วควรมีลักษณะดังนี้:

    app.Use(async (context, next) =>
    {
        await next(); 
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
    });
    

    ในตอนนี้ คอมโพเนนต์ middleware แบบกําหนดเองจะบันทึกรายละเอียดคําขอหลังจากที่คอมโพเนนต์ middleware เทอร์มินัลตั้งค่ารหัสสถานะการตอบสนอง

  2. รีสตาร์ทและทดสอบคําขอ /history อีกครั้ง เอาต์พุตคอนโซลดีบัก ตอนนี้ควรแสดงรหัสสถานะที่ถูกต้อง

    GET / 200
    GET /history 302
    GET /about 200