Daniel Santos
Daniel Santos

Reputation: 15918

ASP.NET MVC. How disable required validation based on a parameter?

I do have a entity class with some required attributes depending of a selector.

For instance: The Selector can assume "1" or "2". If selector was "1", a group of parameters shall be required. If selector is "2" another set of parameters is required.

class MyClass{

    public int Selector {get;set;} // 1 or 2

    public string A_required_for_1 {get;set;}
    public string B_required_for_1 {get;set;}

    public string C_required_for_2 {get;set;}
    public string D_required_for_2 {get;set;}

    public string E_Required_for_both_selectors {get;set;}

}

User should be able to switch between selectors during Create or Edit actions in view.

Client validation is already solved.

How can I deal with it in server validation?

Upvotes: 1

Views: 2124

Answers (2)

Kevin Lee
Kevin Lee

Reputation: 1135

You can either create your own custom validation attribute or use MVC Foolproof Validation and then do:

class MyClass
{

    public int Selector {get;set;} // 1 or 2

    [RequiredIf("Selector == 1", ErrorMessage = "Your Error Message")]
    public string A_required_for_1 {get;set;}

    [RequiredIf("Selector == 1", ErrorMessage = "Your Error Message")]
    public string B_required_for_1 {get;set;}

    [RequiredIf("Selector == 2", ErrorMessage = "Your Error Message")]
    public string C_required_for_2 {get;set;}

    [RequiredIf("Selector == 2", ErrorMessage = "Your Error Message")]
    public string D_required_for_2 {get;set;}

    [Required("Your Error Message")]
    public string E_Required_for_both_selectors {get;set;}

 }

As mentioned by Win it does not seem to have been in active development for a while so you may want to go down the route of creating your own custom validation attribute, which does require more work but you can have a finer control over the validation itself. Choose depending on your needs.

For a custom validation attribute you could do something like this:

public class RequiredIfOtherProperty : ValidationAttribute
{
    private readonly string _otherPropertyName;
    private readonly string _compareValue;

    public RequiredIfOtherProperty(string otherPropertyName, string compareValue)
    {
        _otherPropertyName = otherPropertyName;
        _compareValue = compareValue;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var otherProperty = validationContext.ObjectType.GetProperty(_otherPropertyName);
        if (otherProperty == null)
        {
            return new ValidationResult($"Property '{_otherPropertyName}' does not exist");
        );

        var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
        if (!_compareValue.Equals(otherPropertyValue))
        {
            return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        return null;
    }
}

It should give you a rough idea on what you can do and you can change the actual validation to however you like. You can then use it like a normal attribute e.g.

[RequiredIfOtherProperty("SomeProperty", "ValueToCompareWith")]

Upvotes: 2

Scott Hinshaw
Scott Hinshaw

Reputation: 23

I believe mvcfoolproof will work for this situation [https://foolproof.codeplex.com/][1] It is also available on nuget. It adds additional validation attributes such as

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]

It is very simple to use.

Upvotes: 1

Related Questions