Chris
Chris

Reputation: 28064

Using different validation logic based on input (ASP.NET MVC)

We have a client request to build a web app to be reused across multiple brands. The data structure will remain the same, but certain use cases may dictate that certain fields are required where they might not be for others.

For example, let's say we have a form to capture basic PII, and the view model looks like this:

public class UserViewModel 
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public string Email {get;set;}
    public string Gender {get;set;}
}

Based on, for example, a route data parameter, the validation rules may differ. So I don't really want to hard code the rules as validation attributes. I thought of using a separate validator interface and looking up the correct validator in a dictionary...

public ActionResult DoSomething(UserViewModel model) 
{
    var offer = RouteData.Values["offer"];        
    var validator = validators.ContainsKey(offer) 
        ? validators[offer] : dict["default"];

    validator.Validate(model, ModelState);

    if (ModelState.IsValid) 
    {
        // etc...
    }
}

Is there a cleaner approach to this conditional validation?

Edit: I'm not looking for third party library recommendations folks. I'm looking for advise on structuring the validation to be as flexible as possible.

Upvotes: 0

Views: 111

Answers (2)

Valeklosse
Valeklosse

Reputation: 1017

On your view modal you can inherit from the IValidatableObject in the System.ComponentModel.DataAnnotations namespace then use the Validate method to check for validation based on certain conditions.

i.e.

public class UserViewModel : IValidatableObject
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public string Email {get;set;}
    public string Gender {get;set;}

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        if(string.IsNullOrWhiteSpace(FirstName))
            yield return new ValidationResult("Firstname required", new[] {"FirstName"})
    }
}

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

You may try the excellent FluentValidation library which has a very nice integration with ASP.NET MVC. It would allow you to handle the required validation logic you are looking for.

The validation logic is separate from your models and can be unit tested in isolation.

Upvotes: 1

Related Questions