การเข้าใจ ViewData ใน ASP.NET MVC User Controls

เมื่อทำงานกับ ASP.NET MVC นักพัฒนามักพบสถานการณ์ที่จำเป็นต้องส่งข้อมูลไปยังวิวและยูสเซอร์คอนโทรลอย่างมีประสิทธิภาพ คำถามทั่วไปเกิดขึ้นเมื่อพยายามเข้าถึงข้อมูลในยูสเซอร์คอนโทรลผ่านคอลเลกชัน ViewData ในบล็อกโพสต์นี้ เราจะดำดิ่งลงไปในปัญหาว่าทำไมคุณสมบัติบางอย่างอาจไม่ปรากฏใน ViewData และวิธีการแก้ไขอย่างเหมาะสม

ปัญหา: การเข้าถึง ViewData ใน User Controls

ลองจินตนาการว่าคุณได้สร้างยูสเซอร์คอนโทรลและกำลังพยายามเรนเดอร์ข้อความจากโมเดลโดยใช้คอลเลกชัน ViewData ในคอนโทรลเลอร์ของคุณ คุณอาจเขียนว่า:

return View("Message", new { DisplayMessage = "This is a test" });

แล้ว คุณพยายามเข้าถึงข้อมูลนี้ในยูสเซอร์คอนโทรลด้วย:

<%= ViewData["DisplayMessage"] %>

อย่างไรก็ตาม แทนที่จะได้รับข้อความที่คาดหวัง คุณกลับได้รับค่าที่เป็น null สิ่งนี้อาจทำให้รู้สึกหงุดหงิด ทำให้หลายๆ คนสงสัย: ทำไมคุณสมบัติ DisplayMessage ถึงไม่ได้ถูกเพิ่มลงในคอลเลกชัน ViewData?

การเข้าใจพฤติกรรมของ ViewData

คอลเลกชัน ViewData ถูกออกแบบมาให้ถือคู่กุญแจและค่า ในสถานการณ์ทั่วไป เมื่อคุณส่งอ็อบเจ็กต์อนาโนไมัสให้กับวิว คุณสมบัติของอ็อบเจ็กต์นี้จะไม่มีการเติมข้อมูลลงในดิกชันนารี ViewData โดยอัตโนมัติ พฤติกรรมนี้เกิดจากการออกแบบ ซึ่งหมายความว่าขณะที่วิวของคุณสามารถเข้าถึงคุณสมบัติของโมเดลโดยตรง มันจะไม่นำข้อมูลเหล่านั้นไปเติม ViewData นอกจากจะมีการกำหนดประเภทที่แข็งแกร่ง

ทำไมถึงเป็นเช่นนี้?

  1. ชนิดอนาโนไมส: เมื่อคุณใช้สิ่งที่เป็นอ็อบเจ็กต์อนาโนไมส (เช่นในตัวอย่างของเรา) คุณสมบัติของมันจะไม่ถูกเก็บรักษาในคอลเลกชัน ViewData
  2. ต้องการการกำหนดประเภทที่แข็งแกร่ง: เพื่อให้การเข้าถึงคุณสมบัติเป็นเรื่องง่าย การสร้างโมเดลที่มีการกำหนดประเภทที่แข็งแกร่ง—เช่น คลาส—จะเป็นประโยชน์

วิธีแก้ไข: การกำหนดประเภทที่แข็งแกร่งในยูสเซอร์คอนโทรลของคุณ

เพื่อให้สามารถส่งและเรียกข้อมูลได้อย่างมีประสิทธิภาพในยูสเซอร์คอนโทรลของคุณ คุณสามารถใช้คลาสที่มีการกำหนดประเภทที่แข็งแกร่ง ตัวอย่างเช่น คุณสามารถสร้างคลาส MessageData:

public class MessageData
{
    public string DisplayMessage { get; set; }
}

จากนั้น ปรับปรุงยูสเซอร์คอนโทรลให้เป็นประเภทที่แข็งแกร่งดังนี้:

public class MessageControl : ViewUserControl<MessageData>

ตอนนี้ คุณสามารถเรียกใช้จากคอนโทรลเลอร์ของคุณได้ดังนี้:

return View("Message", new MessageData() { DisplayMessage = "This is a test" });

และเข้าถึงคุณสมบัตินี้ภายในยูสเซอร์คอนโทรลด้วย:

<%= ViewData.Model.DisplayMessage %>

วิธีการทางเลือก

หากคุณต้องการที่จะทำตามการใช้ ViewData และไม่ต้องสร้างคลาสที่มีการกำหนดประเภทที่แข็งแกร่ง คุณสามารถเข้าถึงค่าได้โดยใช้เมธอด ViewData.Eval:

ViewData.Eval("DisplayMessage")

เมธอดนี้จะค้นหาคุณสมบัติภายใน ViewData และจะคืนค่าออกมาหากมันมีอยู่

สรุป

ท้ายที่สุด เมื่อมันเข้าใจได้ว่าใครอาจคาดหวังให้ ViewData รวมคุณสมบัติจากอ็อบเจ็กต์ที่ส่งผ่านแบบอนาโนไมสโดยอัตโนมัติ แต่มันไม่ได้เกิดขึ้นเพราะวิธีที่ ASP.NET MVC จัดการข้อมูลระหว่างโมเดลและวิว การกำหนดประเภทที่แข็งแกร่งในยูสเซอร์คอนโทรลหรือการใช้ ViewData.Eval จะทำให้คุณสามารถเข้าถึงข้อมูลที่คุณต้องการอย่างสำเร็จ

การเข้าใจรายละเอียดเหล่านี้จะทำให้ประสบการณ์การเขียนโค้ดของคุณกับ ASP.NET MVC มีประสิทธิภาพและสนุกสนานยิ่งขึ้น ขอให้สนุกกับการเขียนโค้ด!