如何首先调用类验证属性而不是属性验证属性C#

时间:2019-11-13 14:27:01

标签: c# asp.net-mvc asp.net-core asp.net-core-webapi

我在Web api中有一个具有5个属性的模型。

[CheckAtleastNProperties2(ErrorMessage = "Please provide atleast one property")]
public class Class1
{

    [RequiredIfCustom("Provide either prop1 and prop2 or prop3, prop4 and prop5.", "prop2")]
    public string prop1 { get; set; }
    [RequiredIfCustom("Provide either prop1 and prop2 or prop3, prop4 and prop5.", "prop1")]
    public int prop2 { get; set; }
    [RequiredIfCustom("Provide either prop1 and prop2 or prop3, prop4 and prop5.", "prop4", "prop5")]
    public string prop3 { get; set; }
    [RequiredIfCustom("Provide either prop1 and prop2 or prop3, prop4 and prop5.", "prop3", "prop5")]
    public string prop4 { get; set; }
    [RequiredIfCustom("Provide either prop1 and prop2 or prop3, prop4 and prop5.", "prop3", "prop4")]
    public string prop5 { get; set; }
}

我为类创建了两个自定义属性CheckAtleastNProperties2,为属性创建了RequiredIfCustom,现在我要检查的是检查用户是否提供了至少一个属性,然后检查属性验证RequiredIfCustom()但是不是先检查CheckAtleastNProperties2,而是总是先检查RequiredIfCustom,是否可以检查或强制首先调用类级别验证属性而不是先调用属性级别验证属性?

这是CheckAtleastNProperties2的实现,它检查用户是否提供了至少一个属性的值:

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class CheckAtleastNProperties2 : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var properties = validationContext.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
        if (properties.Where(x => x.GetValue(value, null) != null && x.PropertyType.IsValueType && !x.GetValue(value).Equals(Activator.CreateInstance(x.PropertyType))).Count() != 0)
        {
            return ValidationResult.Success;
        }
        else
        {
            //ErrorMessage = "Provide either Accountnumber and InstitutionID or Fname, Lname and Last4DigitSSN.";
            return new ValidationResult.Success;
        }

    }
}

这是RequiredIfCustomAttribute的实现,它检查用户是否为prop1提供值,然后它应该为prop2提供值,依此类推:

[AttributeUsage(AttributeTargets.Property)]
public class RequiredIfCustomAttribute : ValidationAttribute
{
    private string[] _properties { get; set; }
    private string _errorMessage { get; set; }
    public RequiredIfCustomAttribute(string errorMessage = null, params string[] properties)
    {
        _properties = properties;
        _errorMessage = errorMessage;
    }

    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        //logic for conditional check 
        return ValidationResult.Success;
    }
}

我的问题是,它总是在CheckAtleastNProperties2之前先调用RequiredIfCustom,我希望现在已经清楚了。

1 个答案:

答案 0 :(得分:0)

您需要实现IValidatableObject。将验证检查放入Validate方法中。最后返回错误列表。

public class Class1 : IValidatableObject
{
    public string prop1 { get; set; }
    public int? prop2 { get; set; }
    public string prop3 { get; set; }
    public string prop24 { get; set; }
    public string prop5 { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> errors = new List<ValidationResult>();
        if (string.IsNullOrWhitespace(prop1) && prop2.IsNull && string.IsNullOrWhitespace(prop3) && string.IsNullOrWhitespace(prop4) && string.IsNullOrWhitespace(prop5) &&)
        {
             errors.Add(new ValidationResult($"Please provide at least one property.", new List<string> { }));
        }
        return errors;
    }
}

请参阅Microsoft文档https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-3.0#ivalidatableobject

请参阅原始答案ASP.NET Core Conditional Validation for controls