MVC Validators

17 בנובמבר 2013

תגיות: , , ,
תגובה אחת

אחת התכונות של MVC, היא האפשרות להגדיר על המודל האם הוא Valid או לא – זה נעשה בעזרת Attributes שונים על המאפיינים, לדוגמא.

Code Snippet
public class Person
{
    [Required]
    public string Name { get; set; }

    [Required(AllowEmptyStrings = false)]
    [EmailAddress]
    public string Email { get; set; }
}

כעת במידה ובצד השרת נקבל אובייקט Person נוכל לשאול האם המודל תקין, כך:
 

Code Snippet
public ActionResult Index(Person person)
{
    if (ModelState.IsValid)
    {
        //….
    }

    return View();
}

מה שעוד יותר נחמד, שבמידה ונגדיר את ה – View שלנו בעזרת model של MVC, הוא ייצור עבורנו jquery validators מתאימים, כך שאם יהיה לנו jquery validator בפרוייקט, ה – submit יעצר במידה והמודל לא תקין.

Code Snippet
@model AdvanceMVC4.Models.Person

@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
    <fieldset>
        <legend>Log in Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.Name)
                @Html.TextBoxFor(m => m.Name)
                @Html.ValidationMessageFor(m => m.Name)
            </li>
            <li>
                @Html.LabelFor(m => m.Email)
                @Html.TextBoxFor(m => m.Email)
                @Html.ValidationMessageFor(m => m.Email)
            </li>
        </ol>
        <input type="submit" value="Test" />
    </fieldset>
}

כעת במידה ויהיו לנו את קבצי הסקריפט הבאים: jquery
jquery.validate
jquery.validate.unobtrusive הפנייה לשרת תעמור במידה והמודל לא יעבור בדיקת תקינות.   השלב הבא בחיים שלנו כמפתחים היא להבין כיצד כותבים ולידציות מותאמות אישית, למעשה אין פשוט מזה, נגיד שברצונינו להגיד ולידציה שלא תאפשר לכתוב עברית במחרוזת, כדי לממש זאת נכתוב את המחלקה הבאה:

Code Snippet
public class HebrewValidatorAttribute : ValidationAttribute
{
    public bool Deny { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (!Deny || value == null) return ValidationResult.Success;

        string data = value.ToString();
        bool contain = data.ToCharArray().Any(x => (x <= 'ת' && x >= 'א'));

        if (!contain) return ValidationResult.Success;

        return new ValidationResult(ErrorMessage);
    }

    public override string FormatErrorMessage(string name)
    {
        string format = string.Format("The {0} field contain hebrew characters", name);
        return format;
    }
}

במתודת IsValid נחזיר האם הבדיקה עברה בהצלחה, למעשה יש אופצייה לממש IsValid שמחזירה bool, אבל היא מקבלת כפרמטר רק את ה – value, ב – ovveride הנוכחי, נקבל את ה – ValidationContext שמאפשר לדוגמא לגשת לאובייקט ולשאר המאפיינים שלו אם צריך. כעת במידה ונשנה את מאפיין ה – Name שיראה כך:

Code Snippet
[HebrewValidator(Deny = true)]
public string Name { get; set; }

בזמן שנוודא (בשרת) האם המודל תקין, גם הבדיקה שלנו תרוץ. השאלה הבאה – כיצד נממש את הבדיקה שלנו (אם אפשר) בצד הלקוח. ראשית כל נממש את IClientValidatable, כך:

Code Snippet
public class HebrewValidatorAttribute : ValidationAttribute, IClientValidatable
{
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule rule = new ModelClientValidationRule()
        {
            ErrorMessage = FormatErrorMessage(metadata.PropertyName),
            ValidationType = "ishebrew"
        };
        rule.ValidationParameters["deny"] = Deny.ToString().ToLower();

        yield return rule;
    }

במימוש המתודה, נגדיר את ה – Rule שנוסיף ל – jquery validate, יש מספר מגוון של Rules קיימים, אנחנו נשתמש בבסיס. נשלח ללקוח את הודעת השגיאה, את שם הפונקציה שתהיה בצד הלקוח (חייבים אותיות קטנות ללא הפסק) ונוסיף פרמטרים אם צריך. (להסבר על yield)   כעת נממש את צד הלקוח – (לאחר הקוד שמוריד את קבצי הסקריפט של jQuery, נכתוב כדלהלן)

Code Snippet
<script type="text/javascript">
    $.validator.unobtrusive.adapters.add('ishebrew', ['deny'], function (options) {
        options.rules['ishebrew'] = options.params;
        options.messages['ishebrew'] = options.message;
    });

    $.validator.addMethod("ishebrew", function (value, element, params) {
        if (params.deny == 'false') return true;

        for (var i = 0; i < value.length; i++) {
            if (value.charCodeAt(i) > 0x590 && value.charCodeAt(i) < 0x5FF) {
                return false;
            }
        }

        return true;

    }, ");
</script>
}

כעת – שינוי של הטקסט, יפעיל את הסקריפט שלנו (בעזרת המנגנון של jQuery Validator) ויוודא תקינות עוד לפני הפנייה לשרת.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

תגובה אחת

  1. qseopb@gmail.com18 בנובמבר 2013 ב 8:51

    שלום שלמה,

    בעניין הולידציה, איך ניתן לשמר (מלבד ליצור עותק) את כל ההגדרות ששמתי בקלסים של המודל שלא "ידרסו" כאשר אני מבקש לעדכן את המודל מהדטה בייס עם EF ?

    תודה.

    הגב