Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Custom Validation by DataAnnotation

I have a Model with 4 properties which are of type string. I know you can validate the length of a single property by using the StringLength annotation. However I want to validate the length of the 4 properties combined.

What is the MVC way to do this with data annotation?

I'm asking this because I'm new to MVC and want to do it the correct way before making my own solution.

like image 715
Danny van der Kraan Avatar asked Apr 19 '13 08:04

Danny van der Kraan


People also ask

How do I create a custom validation in C#?

To create a custom validation attributeIn Solution Explorer, right-click the App_Code folder, and then click Add New Item. Under Add New Item, click Class. In the Name box, enter the name of the custom validation attribute class. You can use any name that is not already being used.


2 Answers

You could write a custom validation attribute:

public class CombinedMinLengthAttribute: ValidationAttribute {     public CombinedMinLengthAttribute(int minLength, params string[] propertyNames)     {         this.PropertyNames = propertyNames;         this.MinLength = minLength;     }      public string[] PropertyNames { get; private set; }     public int MinLength { get; private set; }      protected override ValidationResult IsValid(object value, ValidationContext validationContext)     {         var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty);         var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<string>();         var totalLength = values.Sum(x => x.Length) + Convert.ToString(value).Length;         if (totalLength < this.MinLength)         {             return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));         }         return null;     } } 

and then you might have a view model and decorate one of its properties with it:

public class MyViewModel {     [CombinedMinLength(20, "Bar", "Baz", ErrorMessage = "The combined minimum length of the Foo, Bar and Baz properties should be longer than 20")]     public string Foo { get; set; }     public string Bar { get; set; }     public string Baz { get; set; } } 
like image 190
Darin Dimitrov Avatar answered Oct 02 '22 11:10

Darin Dimitrov


Self validated model

Your model should implement an interface IValidatableObject. Put your validation code in Validate method:

public class MyModel : IValidatableObject {     public string Title { get; set; }     public string Description { get; set; }      public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)     {         if (Title == null)             yield return new ValidationResult("*", new [] { nameof(Title) });          if (Description == null)             yield return new ValidationResult("*", new [] { nameof(Description) });     } } 

Please notice: this is a server-side validation. It doesn't work on client-side. You validation will be performed only after form submission.

like image 42
Andrei Avatar answered Oct 02 '22 12:10

Andrei