0

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.

2
  • Look at using foolproof or similar conditional attributes to give you both client and server side validation (or you can write your own) Commented Apr 5, 2016 at 7:15
  • I specifically said I don't want to use attribute-based validation because if the validation requirements change for a given scenario, I don't want to have to touch the model. Commented Apr 5, 2016 at 7:18

2 Answers 2

1

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"})
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.