מדריך ASP.NET MVC – עבודה עם ה-Routing System
כאמור, ASP.NET MVC מורכב מ-3 רכיבים מרכזיים. Controller, View ו-Model. הרכיב הבא בחשיבותו אשר משתתף בכל בקשה חדשה שמגיעה מה-Browser הינו ה-Routing System. רכיב זה אחראי על ניתוח ה-URL וגזירה של אינפורמציה מתוכו.
ניתן לחשוב על ה-Routing System כאל דלת הכניסה לעולם של ASP.NET MVC כאשר רכיב זה מחליט מיהו ה-Controller ומיהו-Action המתאימים שיש להפעיל בכל בקשה שמגיעה מהדפדפן.
ה-Routing System הינו רכיב תשתיתי של ASP.NET כך שניתן להשתמש בו גם באפליקציות WEB מבוססות ASP.NET WebForms. למזלנו, ASP.NET MVC מציע פונקציות שירות מעל ה-Routing System ואנו נשתמש בהן רוב הזמן. באופן כללי, בכל פעם שנרצה לבנות URL חדש מתוך אוסף של נתונים (או להיפך, לנתח URL ולהוציא מתוכו את הנתונים), ה-Routing System הוא הרכיב שישמח לעשות את העבודה בשבילנו.
להורדת הקוד של הפרק הקודם לחץ כאן
כברירת מחדל ASP.NET MVC מגדיר את ה-Routing System כך שכל בקשה מהדפדפן מנותחת באופן הבא:
http:// [WebSite/Application] / [Controller Name] / [Action Name] / [Data to Action] ? [More Data to Action]
את ההגדרה הזו ניתן למצוא בקובץ Global.asax.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Group", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
}
שים לב כי הקוד גם מגדיר ערכי ברירת מחדל כך שאם ה-URL איננו מכיל את הרכיב controller בתוכו אזי הערך המחושב יהיה "Group" או לחילופין אם מוגדר controller אך לא מוגדר action הערך המחושב עבור ה-action יהיה "index".
נניח כי ברצוננו להבטיח כי אם מתקבל URL שנראה באופן הבא: http://AddressBook/Group/56 אזי המערכת תציג את התוכן של הקבוצה שמספרה 56. שים לב כי הדרישה היא שאין צורך להגדיר את שם ה-action בתוך ה-URL.
אם ננסה לפנות ל-URL זה מבלי לשנות דבר בתוכנית אנו נקבל את השגיאה הבאה:
הסיבה לכך היא שה-Routing System מבין כי ה-action הינו "1" וכמובן action שכזה איננו קיים. על מנת לתקן את ההתנהגות הזאת עלינו לשנות את ההגדרות ב-Routing System.
פתח את הקובץ Global.asax.cs וזהה את הפונקציה RegisterRoutes ועדכן אותה באופן הבא:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
null, // Route name
"Group/{id}", // URL with parameters
new { controller = "Group",
action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Group", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
}
שים לב לכניסה החדשה אשר נוספה לטבלת ה-routes המגדירה כי URL אשר נראה בסגנון הבא: "{Group/{id" יטופל ע"י Action בשם Index. הרץ את התוכנית ובחן את ההתנהגות החדשה:
כפי שניתן לראות ה-URL איננו מכיל התייחסות לשם ה-action וה-Routing System יודע ל"נחש" אותו נכונה. מצד שני, אם תילחץ על הלינק "New Group" תיווכח כי משהו איננו מתנהג כשורה והדפדפן מקבל תצוגת פרטים במקום תצוגת יצירה:
שים לכ כיצד ה-URL מבקש Action מסוג Create ולמרות זאת חוזרת לדפדפן תצוגת פרטים של הקבוצה הראשית. הסיבה להתנהגות זאת נובעת מהשינוי שעשינו ב-Routing System. לרוע מזלנו, ה-URL שמוזכר בדוגמא מעלה הינו מתאים מבחינת הצורה שלו להגדרה החדשה שהוספנו והיא: “{Group/{id”. במקרה זה הערך המחושב עבור המשתנה id הינו: "Create" והערך עבור המשתנה action הינו "Index".
הדבר המפתיע הוא שלא מתקבלת שגיאה בזמן שריצה שכן המימוש של הפונקציה Index דורשת משתנה בשם id מסוג int בעוד שהערך "Create" איננו מספר:
public ActionResult Index(int? id, bool? desc)
{
...
}
הסיבה שאיננו מקבלים שגיאה היא שהפרמטר id הינו Nullable. במקרה כזה הפרמטר נחשב כאופציונאלי ובמידה ולא ניתן לאתחל אותו מהערך שמגיע מה-URL הוא מקבל את הערך null. ערך זה (עפ"י המימוש של הפונקציה) משמש בתור ייצוג של קבוצת השורש בספר.
על מנת לפתור את ההתנהגות הלא רצויה עלינו להגדיר טוב יותר את הכניסות ב-Routing System. בפרק הבא אנו נלמד על אילוצים ונראה כיצד לפתור בעיה זו באלגנטיות. בינתיים, ניתן לפתור את הבעיה באופן הבא:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
null, // Route name
"Group/Create", // URL with parameters
new { controller = "Group",
action = "Create" } // Parameter defaults
);
routes.MapRoute(
null, // Route name
"Group/Edit/{id}", // URL with parameters
new { controller = "Group",
action = "Edit" } // Parameter defaults
);
routes.MapRoute(
null, // Route name
"Group/{id}", // URL with parameters
new { controller = "Group",
action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Group", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
}
שים לב כיצד הוספנו הגדרות נוספות בעדיפות יותר גבוהה על מנת לטפל נקודתית במקרה של "Create" ו-"Edit". הרץ את התוכנית ובחן את ההתנהגות הנכונה:
בפרק זה למדנו כיצד ניתן לשנות את הגדרות ברירת המחדל של ה-Routing System וליצור URL יותר נקי ופשוט.
בפרק הבא אנו נמשיך לחקור את היכולות של ה-Routing System ונכיר כיצד להגדיר אילוצים.
תגובות בפייסבוק