验证未知类型的集合或枚举

问题描述 投票:0回答:3

我正在寻找向我的模型添加属性验证,以确保集合属性具有项目。也许有更好的方法来验证我的模型中的集合。如果是这样,我很乐意使用它。

否则,我可以将对象转换为 IEnumerable,但作为接口我不能使用 .Any()。我试图在运行时使用反射来获得更具体的类型,但今天必须戴上我的虚拟帽子。

public class MyModel
{
    ... // other properties
    [CollectionHasAtLeastOne]
    public virtual ICollection<MyItemObject> Items { get; set; }
}

在我的

CollectionHasAtLeastOneAttribute : ValidationAttribute
课上:

protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
    var testObject = (IEnumerable)value; // Can I read the type and cast to that?
    if (testObject == null)
    {
        return new ValidationResult("Collection object cannot be null.");
    }

    if (!testObject.Any()) // Can't use .Any() here
    {
        return new ValidationResult("Collection must have records.");
    }

    return ValidationResult.Success;
}
c# casting ienumerable
3个回答
1
投票

由于协方差,你仍然可以转换为

IEnumerable<object>

var testObject = (IEnumerable<object>)value;

这里是协方差的定义


0
投票

您可以通过使用枚举器本身来避免强制转换和 LINQ。

protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
    if (value is not IEnumerable testObject)
    {
        return new ValidationResult("Collection object cannot be null.");
    }

    if (!testObject.GetEnumerator().MoveNext())
    {
        return new ValidationResult("Collection must have records.");
    }

    return ValidationResult.Success;
}

-1
投票

检查

ICollection
功能

public interface ICollection : IEnumerable
{
    int Count { get; }
    bool IsSynchronized { get; }
    object SyncRoot { get; }
    void CopyTo(Array array, int index);
}

更新

您可以将类型传递给验证属性

CollectionHasAtLeastOneAttribute<T>

public class CollectionHasAtLeastOneAttribute<T> : ValidationAttribute
{
    protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
    {
        if (value == null) throw new ArgumentNullException("value");


        var testObject = value as IEnumerable<T>; // Can I read the type and cast to that?
        if (testObject == null)
        {
            return new ValidationResult("Collection object cannot be null.");
        }

        if (testObject.Any())
        {
            return new ValidationResult("Collection must have records.");
        }

        return ValidationResult.Success;
    }
}




public class MyModel
{

    [CollectionHasAtLeastOne<MyItemObject>]
    public virtual ICollection<MyItemObject> Items { get; set; }
}

解决方法,支持旧的 C# 版本

public Type Type { get; set; }
protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
    if (value == null) throw new ArgumentNullException("value");


    var testObject = value as IEnumerable<Type>; // Can I read the type and cast to that?
    if (testObject == null)
    {
        return new ValidationResult("Collection object cannot be null.");
    }

    if (testObject.Any())
    {
        return new ValidationResult("Collection must have records.");
    }

    return ValidationResult.Success;
}

[CollectionHasAtLeastOneWithTypeAttribute(Type = typeof(MyItemObject))]
© www.soinside.com 2019 - 2024. All rights reserved.