Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel validation for a List

I have the following viewmodel definition

public class AccessRequestViewModel {     public Request Request { get; private set; }     public SelectList Buildings { get; private set; }     public List<Person> Persons { get; private set; } } 

So in my application there must be at least 1 person for an access request. What approach might you use to validate? I don't want this validation to happen in my controller which would be simple to do. Is the only choice a custom validation attribute?

Edit: Currently performing this validation with FluentValidation (nice library!)

RuleFor(vm => vm.Persons)                 .Must((vm, person) => person.Count > 0)                 .WithMessage("At least one person is required"); 
like image 554
ryan Avatar asked Feb 28 '11 19:02

ryan


People also ask

How do I use CustomValidationAttribute?

You apply the CustomValidationAttribute attribute to an entity or one of its members when you need to specify a method to use for validating the entity or the value of the member. Using the first overload is the same as defining custom validation logic for an individual value.

How do you validate a model?

Models can be validated by comparing output to independent field or experimental data sets that align with the simulated scenario.

How can we implement validation in MVC?

Adding Validation to ModelThe validation attributes specify behavior that you want to enforce on the model properties they are applied to. The Required and MinimumLength attributes indicates that a property must have a value; but nothing prevents a user from entering white space to satisfy this validation.


2 Answers

If you are using Data Annotations to perform validation you might need a custom attribute:

public class EnsureOneElementAttribute : ValidationAttribute {     public override bool IsValid(object value)     {         var list = value as IList;         if (list != null)         {             return list.Count > 0;         }         return false;     } } 

and then:

[EnsureOneElement(ErrorMessage = "At least a person is required")] public List<Person> Persons { get; private set; } 

or to make it more generic:

public class EnsureMinimumElementsAttribute : ValidationAttribute {     private readonly int _minElements;     public EnsureMinimumElementsAttribute(int minElements)     {         _minElements = minElements;     }      public override bool IsValid(object value)     {         var list = value as IList;         if (list != null)         {             return list.Count >= _minElements;         }         return false;     } } 

and then:

[EnsureMinimumElements(1, ErrorMessage = "At least a person is required")] public List<Person> Persons { get; private set; } 

Personally I use FluentValidation.NET instead of Data Annotations to perform validation because I prefer the imperative validation logic instead of the declarative. I think it is more powerful. So my validation rule would simply look like this:

RuleFor(x => x.Persons)     .Must(x => x.Count > 0)     .WithMessage("At least a person is required"); 
like image 154
Darin Dimitrov Avatar answered Sep 22 '22 12:09

Darin Dimitrov


Following code works in asp.net core 1.1.

[Required, MinLength(1, ErrorMessage = "At least one item required in work order")] public ICollection<WorkOrderItem> Items { get; set; } 
like image 37
rahulmohan Avatar answered Sep 22 '22 12:09

rahulmohan