如何将验证属性应用于集合中的对象

本文关键字:集合 对象 应用于 属性 验证 | 更新日期: 2023-09-27 17:49:58

基本上,如果我有一个对象集合,我如何将验证属性应用于集合中的每个项目(例如MaxLengthAttribute)?

public class Foo
{
    public ICollection<string> Bars { get; set; }
}
例如,如何确保Bars包含最大长度为256的字符串?更新:

我理解如何在单个属性上应用验证属性,但问题是如何将其应用于集合中的对象

public class Foo
{
    [StringLength(256)] // This is obvious
    public string Bar { get; set; }
    // How do you apply the necessary attribute to each object in the collection!
    public ICollection<string> Bars { get; set; }
}

如何将验证属性应用于集合中的对象

我知道这个问题有点老了,但也许有人会来寻找答案。

我不知道将属性应用于集合项的通用方法,但对于特定字符串长度的示例,我使用了以下方法:

public class StringEnumerationLengthValidationAttribute : StringLengthAttribute
{
    public StringEnumerationLengthValidationAttribute(int maximumLength)
        : base(maximumLength)
    { }
    public override bool RequiresValidationContext { get { return true; } }
    public override bool IsValid(object value)
    { return false; }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var e1 = value as IEnumerable<string>;
        if (e1 != null) return IsEnumerationValid(e1, validationContext);
        return ValidationResult.Success; // what if applied to something else than IEnumerable<string> or it is null?
    }
    protected ValidationResult IsEnumerationValid(IEnumerable<string> coll, ValidationContext validationContext)
    {
        foreach (var item in coll)
        {
            // utilize the actual StringLengthAttribute to validate the items
            if (!base.IsValid(item) || (MinimumLength > 0 && item == null))
            {
                return new ValidationResult(base.FormatErrorMessage(validationContext.DisplayName));
            }
        }
        return ValidationResult.Success;
    }
}

按如下方式应用,每个集合项需要4-10个字符:

[StringEnumerationLengthValidation(10, MinimumLength=4)]
public ICollection<string> Sample { get; set; }

我找到了一篇很好的文章,解释了一些关于这方面的有用信息:

http://blogs.msdn.com/b/codeanalysis/archive/2006/04/27/faq-why-does-donotexposegenericlists-recommend-that-i-expose-collection-lt-t-gt-instead-of-list-lt-t-gt-david-kean.aspx

下面是一些建议的代码,可以使Foo的Bars成员做你想做的事情。

public class Foo
{
    public ValidatedStringCollection Bars = new ValidatedStringCollection(10);
}
public class ValidatedStringCollection : Collection<string>
{
    int _maxStringLength;
    public ValidatedStringCollection(int MaxStringLength)
    {
        _maxStringLength = MaxStringLength;
    }
    protected override void InsertItem(int index, string item)
    {
        if (item.Length > _maxStringLength)
        {
            throw new ArgumentException(String.Format("Length of string '"{0}'" is beyond the maximum of {1}.", item, _maxStringLength));
        }
        base.InsertItem(index, item);
    }
}
class Program
{
    static void Main(string[] args)
    {
        Foo x = new Foo();
        x.Bars.Add("A");
        x.Bars.Add("CCCCCDDDDD");
        //x.Bars.Add("This string is longer than 10 and will throw an exception if uncommented.");
        foreach (string item in x.Bars)
        {
            Console.WriteLine(item);
        }
        Console.ReadKey();
    }
}

链接的文章有几个建议,包括覆盖集合上的其他方法,有条件地实现事件等。这应该涵盖了你。

看一下数据注释功能:

这个对你有用吗?

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class Foo
{  
    [StringLength(256)]
    public ICollection<string> Bars { get; set; }
}