我可以使用DataAnnotations来验证集合属性吗?

3

我有一个WebAPI2控制器的模型,其中有一个字段用于接收(List)字符串集合。是否有一种方法可以指定DataAnnotations(例如[MaxLength])来确保通过验证,列表中的任何字符串长度都不超过50个字符?

    public class MyModel
    {
        //...

        [Required]
        public List<string> Identifiers { get; set; }

        // ....
    }

我宁愿不去创建一个仅仅用来包装字符串的新类。

2个回答

3

可以编写自己的验证属性,例如:

public class NoStringInListBiggerThanAttribute : ValidationAttribute
{
    private readonly int length;

    public NoStringInListBiggerThanAttribute(int length)
    {
        this.length = length;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var strings = value as IEnumerable<string>;
        if(strings == null)
            return ValidationResult.Success;

        var invalid = strings.Where(s => s.Length > length).ToArray();
        if(invalid.Length > 0)
            return new ValidationResult("The following strings exceed the value: " + string.Join(", ", invalid));

        return ValidationResult.Success;
    }
}

您可以直接将其放置在您的物业上:
[Required, NoStringInListBiggerThan(50)]
public List<string> Identifiers {get; set;}

1
我可能想要执行 [ValidateCollection(new MaxLengthAttribute(50))],以便允许应用任何其他属性而无需每个自定义一个。希望框架中有类似的东西,但这将是备选计划。 - Sean B

0

我知道这个问题已经很老了,但是对于那些偶然发现它的人,这是我根据被接受的答案所启发的自定义属性版本。它利用StringLengthAttribute来完成繁重的工作。

/// <summary>
///     Validation attribute to assert that the members of an IEnumerable&lt;string&gt; property, field, or parameter does not exceed a maximum length
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class EnumerableStringLengthAttribute : StringLengthAttribute
{
    /// <summary>
    ///     Constructor that accepts the maximum length of the string.
    /// </summary>
    /// <param name="maximumLength">The maximum length, inclusive.  It may not be negative.</param>
    public EnumerableStringLengthAttribute(int maximumLength) : base(maximumLength)
    {
    }
    
    /// <summary>
    ///     Override of <see cref="StringLengthAttribute.IsValid(object)" />
    /// </summary>
    /// <remarks>
    ///     This method returns <c>true</c> if the <paramref name="value" /> is null.
    ///     It is assumed the <see cref="RequiredAttribute" /> is used if the value may not be null.
    /// </remarks>
    /// <param name="value">The value to test.</param>
    /// <returns><c>true</c> if the value is null or the length of each member of the value is between the set minimum and maximum length</returns>
    /// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
    public override bool IsValid(object? value)
    {
        return value is null || ((IEnumerable<string>)value).All(s => base.IsValid(s));
    }
}

编辑:base.IsValid(s) 如果s为空,则返回true,因此如果字符串成员不得为空,请改用以下方法:
public override bool IsValid(object? value)
{
    return value is null || ((IEnumerable<string>)value).All(s => !string.IsNullOrEmpty(s) && base.IsValid(s));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接