How to remove a single error from a property with

2019-06-09 02:56发布

问题:

In my ViewModel I have a property with multiple validation errors like this

[Required(ErrorMessage = "Required")]
[RegularExpression(@"^(\d{1,2})$", ErrorMessage = "Only numbers admitted")]
[MaxLength(3, ErrorMessage = "MaxLength is 3")]
public string MyField { get; set; }

The "Required" validation depends on user input on another field, so in the controller I want to remove the error from the ModelState. The only way to do it that I found is like this:

if (view.OtherField != null && view.OtherField.Trim() != "" && ModelState.ContainsKey("MyField"))
{
    //removing all errors from "MyField"
    ModelState["MyField"].Errors.Clear();

    //checking length
    if (view.MyField.Length > 3)
        ModelState.AddModelError("MyField", "MaxLength is 3");

    //checking the value
    Regex regex = new Regex(@"(\d{1,2})");

    if (!regex.IsMatch(view.MyField))
        ModelState.AddModelError("MyField", "Only numbers admitted");
}

Is there a way to selectively remove only the "Required" error without having to remove the whole ModelState error of the MyField property and then re-adding the other errors?

回答1:

For your purpose you have to make custom validation attribute like [RequiredIf] :-

[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true)]
public class RequiredIfAttribute : RequiredAttribute
{
    private string OtherProperty { get; set; }
    private object Condition { get; set; }

    public RequiredIfAttribute(string otherProperty, object condition)
    {
        OtherProperty = otherProperty;
        Condition = condition;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(OtherProperty);
        if (property == null)
            return new ValidationResult(String.Format("Property {0} not found.", OtherProperty));

        var propertyValue = property.GetValue(validationContext.ObjectInstance, null);
        var conditionIsMet = Equals(propertyValue, Condition);
        return conditionIsMet ? base.IsValid(value, validationContext) : null;
    }
}

Model :-

[RequiredIf("OtherField", "")]
[RegularExpression(@"^(\d{1,2})$", ErrorMessage = "Only numbers admitted")]
[MaxLength(3, ErrorMessage = "MaxLength is 3")]
public string MyField { get; set; }

public string OtherField {get; set;}

In above answer if OtherField value is empty than MyField is required otherwise not..