การเข้าใจ 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
นอกจากจะมีการกำหนดประเภทที่แข็งแกร่ง
ทำไมถึงเป็นเช่นนี้?
- ชนิดอนาโนไมส: เมื่อคุณใช้สิ่งที่เป็นอ็อบเจ็กต์อนาโนไมส (เช่นในตัวอย่างของเรา) คุณสมบัติของมันจะไม่ถูกเก็บรักษาในคอลเลกชัน
ViewData
- ต้องการการกำหนดประเภทที่แข็งแกร่ง: เพื่อให้การเข้าถึงคุณสมบัติเป็นเรื่องง่าย การสร้างโมเดลที่มีการกำหนดประเภทที่แข็งแกร่ง—เช่น คลาส—จะเป็นประโยชน์
วิธีแก้ไข: การกำหนดประเภทที่แข็งแกร่งในยูสเซอร์คอนโทรลของคุณ
เพื่อให้สามารถส่งและเรียกข้อมูลได้อย่างมีประสิทธิภาพในยูสเซอร์คอนโทรลของคุณ คุณสามารถใช้คลาสที่มีการกำหนดประเภทที่แข็งแกร่ง ตัวอย่างเช่น คุณสามารถสร้างคลาส 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 มีประสิทธิภาพและสนุกสนานยิ่งขึ้น ขอให้สนุกกับการเขียนโค้ด!