מדריך ASP.NET MVC

מדריך ASP.NET MVC – שימוש ב- Filters

‏ • Hi Tech

Filters הינם Attributes אשר ניתן להצמיד אותם ל-Actions מסוימים וזאת על מנת לשנות או להוסיף על ההתנהגות של ה-Action עצמו.

Filters הינם דרך מצוינת להוסיף יכולות חדשות לתוכנית שלך מבלי לגעת בקוד הקיים. בנוסף, ה-Filter יכול להכיל קוד אשר מסיבות ארכיטקטוניות אנו מעדיפים שיישב מחוץ ל-Controller. לדוגמא, קוד אשר קשה ליצור תוכנית בדיקה עבורו ולכן איננו רוצים "לערבב" אותו עם קוד שאפשר לבודקו.

דוגמא מצוינת ל-Filters ראינו בפרק שעוסק בהרשאות, שם השתמשנו ב-Filter Authorize על מנת לציין כי Controller או Action מסוימים אינם נגישים למשתמש שאיננו מזוהה. השימוש ב-Filter על מנת לנהל תהליכי זיהוי הינו דרך לשמור על הקוד של ה-Controller נקי כך שניתן לבדוק אותו בקלות מתוך Unit Test. כמובן ה-Filter מאפשר שימוש חוזר בו בצורה פשוטה בכמה Controllers או Actions שונים בו זמנית.

להורדת הקוד של הפרק הקודם לחץ כאן

נכון לעכשיו, ספר הכתובות איננו מאפשר למשתמש שאיננו admin לבצע פעולות במערכת. כאשר משתמש שאיננו admin, לדוגמא ori מנסה למחוק פריט בספר הוא מופנה לתצוגת ה-login. התנהגות זו עלולה להיות מבלבלת מאחר והמשתמש כבר זוהה בהצלחה. אנו נתקן התנהגות זו ע"י הגדרה ושימוש ב-Filter חדש בשם "AuthorizeEx".

פתח את ה-Solution Explorer והוסף מחלקה חדשה תחת הקובץ Filters\AuthorizeEx.cs. שים לב כי המחיצה Filters איננה קיימת ועליך ליצור אותה ידנית. ערוך את התוכן של הקובץ:

public class AuthorizeExAttribute : AuthorizeAttribute
{
  protected override void HandleUnauthorizedRequest(
AuthorizationContext filterContext)
  {
    string url = RouteTable.Routes.GetVirtualPath(
            filterContext.RequestContext,
new RouteValueDictionary() {
              { "action", "Unauthorized" },
              { "controller", "Book" } }).VirtualPath;

    filterContext.HttpContext.Response.Redirect(url);
  }
}

שים לב כיצד המחלקה החדשה AuthorizeExAttribute יורשת ממחלקת התשתית AuthorizeAttribute. המחלקה הבסיסית כבר מממשת את כל הלוגיקה הקשורה בזיהוי המשתמש ובהרשאותיו. כל מה שנשאר לנו לעשות זה לדרוס את המתודה HandleUnauthorizeRequest ולהגדיר התנהגות חדשה עבור המקרה שלמשתמש אין הרשאות לבצע פעולה מסוימת במערכת.

במידה ואין הרשאות מתאימות ה-Filter מפנה את המשתמש ל-BookController ול-Unauthorized Action שבתוכו. בנוסף, שים לב לשימוש במחלקה RouteTable המשמשת לבניית URL מתוך שם ה-Controller ושם ה-Action. בפרקים יותר מתקדמים במדריך אנו נבין יותר לעומק את אופן העבודה עם המחלקה RouteTable.

הוסף Action בשם Unauthorized למחלקה BookController:

[HttpGet]
public ActionResult Unauthorized()
{
  return View();
}

צור View חדש עבור ה-Action Unauthorized:

@{
    ViewBag.Title = "Unauthorized";
}

<div class="unauthroized">
    <hr />
    You are not authorized to perform this operation
</div
>

עדכן את כל ה-Actions אשר מעוטרים ב-Filter בשם Authorize והשתמש במקומו ב-Filter החדש AuthorizeEx. לדוגמא ה-Action בשם Create במחלקה GroupController:

[HttpGet]
[AuthorizeEx(Roles = "admin")]
public ActionResult Create(int parentId)
{
  AddressBookDB db = AddressBookDB.Create();

  Group parent = (Group)db.GetItemByID(parentId);
  Group newGroup = new Group() { Parent = parent };

  return View(newGroup);
}

שים לב כי אין לעדכן את ה-Filters אשר מעטרים את המחלקות עצמן.

הרץ את התוכנית. היכנס למערכת תחת שם המשתמש ori ונסה לשנות/למחוק פריטים בספר. ההודעה הבאה אמורה להופיע:

image

יש לציין כמה נקודות חשובות לגבי Filters:

  • Filter נחשב ככזה רק אם הוא יורש מהמחלקה FilterAttribute
  • ASP.NET MVC מגדיר 4 סוגי Filters:
    • IAuthorizationFilter – זהו הפילטר הראשון אשר מקבל הזדמנות לטפל בבקשה חדשה שמגיעה מה-Browser
    • IActionFilter – פילטר אשר מקבל הזדמנות לרוץ לפני ואחרי ש-Action מסוים רץ.
    • IResultFilter – פילטר אשר מקבל הזדמנות לרוץ לפני ואחרי ש-Action Result מסוים רץ. פילטר זה רץ אחרי ה-IActionFilter.
    • IExceptionFilter – פילטר אשר מקבל הזדמנות לרוץ רק אם אחד מה-Filters הקודמים, ה-Action עצמו או ה-Action Result הסתיימו בשגיאה.

סה"כ במידה ו-Filter מסוים מממש את כל הממשקים שהוזכרו מעלה אזי רשימת האירועים עפ"י סדרם היא:

  1. OnAuthorization
  2. OnActionExecuting
  3. OnActionExecuted
  4. OnResultExecuting
  5. OnResultExecuted
  6. OnException – רק אם הייתה שגיאה

כמובן, Filter איננו חייב לממש את כל הממשקים המוזכרים מעלה אלא רק את אלו שמעניינים אותו.

 

בפרק זה למדנו להגדיר Filter חדש ולהשתמש בו בכמה Actions שונים ברחבי התוכנית. בפרק הבא נלמד על סוג מסוים של Filter אשר נקרא GlobalFilter.

תגיות: , , , ,

תגובות בפייסבוק