การลบโนดจาก SiteMapNodeCollection ใน ASP.NET

การจัดการการนำทางของแอปพลิเคชัน ASP.NET ของคุณนั้นเป็นสิ่งสำคัญสำหรับการให้ประสบการณ์ผู้ใช้ที่ดีที่สุด อย่างไรก็ตาม อาจมีกรณีที่คุณต้องการ ไม่ให้บางหน้า ปรากฏในนำทางของเว็บไซต์ของคุณ เช่น แบบฟอร์มลงทะเบียน หากคุณใช้ Repeater เพื่อแสดงโนดย่อยของ SiteMap คุณอาจสงสัยว่า จะลบโนดที่เฉพาะเจาะจงออกไปได้อย่างไรโดยไม่เกิดปัญหาเช่น NotSupportedException ที่แสดงว่า คอลเล็กชันอ่านได้เท่านั้น บล็อกนี้จะชี้แนะคุณผ่านทางออกสำหรับปัญหานี้

การเข้าใจปัญหา

ใน ASP.NET, SiteMapNodeCollection มักจะถูกใช้เพื่อแสดงโครงสร้างของหน้าเว็บไซต์ของคุณ โครงสร้างนี้อาจมีประโยชน์โดยเฉพาะเมื่อคุณผูกข้อมูลกับการควบคุมเช่น Repeater อย่างไรก็ตาม หากคุณต้องการซ่อนหน้าเฉพาะ เช่น แบบฟอร์มลงทะเบียน จากรายการนำทางของคุณ การพยายาม Remove พวกมันออกจากคอลเล็กชันอาจทำให้เกิดข้อผิดพลาดเนื่องจาก SiteMapNodeCollection อ่านได้เท่านั้น

นี่คือภาพรวมด่วนเกี่ยวกับสถานการณ์:

สถานการณ์ตัวอย่าง:

  • ประเภทควบคุม: Repeater
  • แหล่งข้อมูล: SiteMapNodeCollection จาก web.sitemap
  • เป้าหมาย: ไม่ให้หน้าเว็บลงทะเบียน (/Registration.aspx) ปรากฏในรายการหน้าที่แสดง

ความท้าทาย

การใช้เมธอด Remove() บน SiteMapNodeCollection จะนำไปสู่ข้อผิดพลาดดังนี้:

NotSupportedException: “Collection is read-only”.

ทางออก

เพื่อที่จะไม่ให้โนดเฉพาะเจาะจงปรากฏ คุณไม่จำเป็นต้องแก้ไข SiteMapNodeCollection ดั้งเดิมจริงๆ แทนที่จะเป็นเช่นนั้น คุณสามารถสอบถามคอลเล็กชันและสร้างคอลเล็กชันใหม่ที่มีเฉพาะโนดที่ต้องการแสดง นี่คือวิธีการทำเช่นนี้โดยใช้ LINQ

วิธีการตามขั้นตอน

  1. สอบถามโนดย่อย: ใช้ LINQ เพื่อกรองโนดที่ไม่ต้องการออกจากคอลเล็กชัน ChildNodes
  2. เลือกโนดที่ต้องการ: สร้างคอลเล็กชันใหม่ที่ไม่รวมหน้าเว็บลงทะเบียน
  3. ผูกคอลเล็กชันใหม่: ตั้ง DataSource ของ Repeater ของคุณไปยังคอลเล็กชันใหม่

ตัวอย่างการใช้งานโค้ด

นี่คือโค้ด VB.NET ที่แนะนำเพื่อให้บรรลุผลตามต้องการ:

Dim children = From n In SiteMap.CurrentNode.ChildNodes.Cast(Of SiteMapNode)()
               Where n.Url <> "/Registration.aspx"
               Select n

RepeaterSubordinatePages.DataSource = children
RepeaterSubordinatePages.DataBind() ' อย่าลืมผูก Repeater

การวิเคราะห์ของโค้ด:

  • การสอบถาม: โค้ดใช้การสอบถาม LINQ เพื่อกรองโนดที่ URL เท่ากับ /Registration.aspx
  • การแคสต์: Cast(Of SiteMapNode)() เป็นสิ่งสำคัญในขณะที่ช่วยให้ LINQ รู้จักคอลเล็กชันเป็นชุดของ SiteMapNode objects
  • การผูก: หลังจากการกรอง คอลเล็กชัน children ที่ได้จะถูกตั้งเป็น DataSource สำหรับ Repeater และเรียกใช้ DataBind() เพื่ออัปเดตการควบคุม

สรุป

โดยการใช้ LINQ กรองโนดเฉพาะจาก SiteMapNodeCollection คุณสามารถหลีกเลี่ยงปัญหาที่เกิดจากการพยายามแก้ไขคอลเล็กชันที่อ่านได้เท่านั้น วิธีนี้ไม่เพียงแต่ทำให้โค้ดของคุณสะอาดและมีประสิทธิภาพ แต่ยังมั่นใจว่าการนำทางจะแสดงเฉพาะหน้าที่คุณคิดว่าจำเป็น

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