קצת רקע
הייתי ממליץ בחום לקרוא את המאמר הזה: http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html
מה עושים עכשיו?
אנחנו נבנה אפליקציה קטנה של “משפחה”. באפליקציה נתרכז רק בחלק של ולידציה.
אפליקציה תכלול כמה שדות כגון:
שם מלא
גיל האב
גיל הבן
הולידציה שנבה היא:
הגיל של הבן חייב להיות קטן לפחות ב 15 שנים מגיל האב (קצת מוקדם מדי לעשות ילדים בגיל 14…)
את הקוד תוכלו להוריד בסוף המאמר
מספיק עם הבלה בלה…. בוא נכתוב קוד!!!
ניצור אפליקצית MVC3 חדשה ונריץ אותה:

נכין את המודל שלנו:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public double Age { get; set; }
public double FatherAge { get; set; }
}
הגיע זמן להכין את Controller
public class HomeController : Controller
{
public ActionResult Index( )
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About( )
{
return View();
}
public ActionResult Create( )
{
return View( new User() );
}
}
וה View


נריץ את האפליקציה:

זה הזמן לולידציה
public class User
{
public int Id { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
[Range(1,100)]
public double Age { get; set; }
[Range( 1 , 100 )]
public double FatherAge { get; set; }
}
נריץ שוב

לאחר התחממנו קצת הגיע זמן לבנות ולידטור משלנו!!!
נוסף פרוייקט חדש מסוג Class Lybrary (למען הסדר הטוב וניצור בו Class בשם AgeCompareAttribute)
*שימו לב שחובה לשים סיומת לשם שלכם – Attribute.
הClass שלנו יורש מ
ValidationAttribute – ולידציה בצד השרת
IClientValidatable – ולידציה בצד הלקוח
namespace AgeValidator
{
public class AgeCompareAttribute : ValidationAttribute , System.Web.Mvc.IClientValidatable
{
#region IClientValidatable Members
public IEnumerable<ModelClientValidationRule> GetClientValidationRules( ModelMetadata metadata , ControllerContext context )
{
throw new NotImplementedException();
}
#endregion
}
}
הקוד הבא יראה קצת מפחיד, אבל אל תחששו, יש עוד קצת בדרך :)
namespace AgeValidator
{
public class AgeCompareAttribute : ValidationAttribute , System.Web.Mvc.IClientValidatable
{
private const string DefaultErrorMessageFormatString = "'{0}' must be lower than {1} by 15 year a least.";
private string _DependentPropertyDisplayName = null;
public string DependentProperty { get; set; }
/// <summary>
/// Construcror
/// </summary>
/// <param name="DependentProperty">Model Dependent Property</param>
public AgeCompareAttribute( string DependentProperty )
: base( DefaultErrorMessageFormatString )
{
this.DependentProperty = DependentProperty;
}
/// <summary>
/// Format Error Message
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string FormatErrorMessage( string name )
{
return String.Format( DefaultErrorMessageFormatString , name , ( this._DependentPropertyDisplayName ?? this.DependentProperty ) );
}
protected override ValidationResult IsValid( object value , ValidationContext validationContext )
{
return ValidationResult.Success;
}
#region IClientValidatable Members
public IEnumerable<ModelClientValidationRule> GetClientValidationRules( ModelMetadata metadata , ControllerContext context )
{
throw new NotImplementedException();
}
#endregion
}
}
עכשיו לקצת הסברים:
DependentProperty – זהו משתנה שאיתו נעשה את ההשוואה (במקרה שלנו עם האב)
FormatErrorMessage – עיצוב ההודעה שתוצג למשתמש
IsValid – ולידציה בפועל
הגיע זמן לרשום את הולידציה
protected override ValidationResult IsValid( object value , ValidationContext validationContext )
{
// Get Depented Proprety
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty( this.DependentProperty );
if ( field != null )
{
this._DependentPropertyDisplayName = field.Name;
var dependentvalue = field.GetValue( validationContext.ObjectInstance , null );
if ( dependentvalue != null && value != null )
{
double _value = Convert.ToDouble(value);
double _dependentvalue = Convert.ToDouble(dependentvalue);
//validate
if((_dependentvalue - _value) < 15)
return new ValidationResult( FormatErrorMessage( validationContext.DisplayName ) , new[ ] { validationContext.MemberName } );
}
}
return ValidationResult.Success;
}
בוא נריץ את האפליקציה שלנו:

איזה יופי! הולידציה בצד השרת עובדת מעולה!!!
במאמר הבא נבנה את הצד הלקוח של האפליקצה