Validating page data with Data Annotations
Jarle posted a very inspiring post about validating your PageData object upon save. This is a quick post that uses the same technique but uses Data Annotations for validation.
If you’re not familiar with data annotations basically it’s a way to validate your entities by decorating properties with various validation attributes that lives in the System.ComponentModel.DataAnnotations namespace.
Let’s say we have this property in our TypedPageData class
1: [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "/validationerror/mainbodyisempty")]
2: [System.ComponentModel.DataAnnotations.StringLength(15, ErrorMessage = "/validationerror/mainbodyistoolong")]
3: [PageTypeProperty(SortOrder = 100, UniqueValuePerLanguage = true, Searchable = true, Type = typeof(PropertyLongString), Tab = typeof(Tabs.Information))]
4: public virtual string MainBody
5: {
6: get;
7: set;
8: }
In this case I’ve used a path as the ErrorMessage to be able to use the EpiServer functionality of the language xml files. The following simple class validates a given object by finding all properties marked with a ValidationAttribute.
1: public class PageDataValidator
2: {
3: public IEnumerable<string> GetErrors(object toValidate)
4: {
5: return TypeDescriptor
6: .GetProperties(toValidate)
7: .Cast<PropertyDescriptor>()
8: .SelectMany(prop =>
9: prop.Attributes.OfType<ValidationAttribute>(),
10: (prop, attribute) => new { prop, attribute })
11: .Where(@t1 => !@t1.attribute.IsValid(@t1.prop.GetValue(toValidate)))
12: .Select(@t1 => LanguageManager.Instance.Translate(@t1.attribute.ErrorMessage));
13: }
14: }
In the GlobalPageValidation we simply initiate our PageDataValidator class and performs some simple logic to set the appropriate error(s).
1: void GlobalPageValidation_Validators(object sender, PageValidateEventArgs e)
2: {
3: PageDataValidator validator = new PageDataValidator();
4: var errors = validator.GetErrors(e.Page);
5:
6: if (errors.Count() > 0)
7: {
8: e.IsValid = false;
9: foreach(var error in errors)
10: {
11: e.ErrorMessage += error;
12: }
13:
14: }
15: }
Nice, works fine thank you! =)