我正在寻找向我的模型添加属性验证,以确保集合属性具有项目。也许有更好的方法来验证我的模型中的集合。如果是这样,我很乐意使用它。
否则,我可以将对象转换为 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;
}
您可以通过使用枚举器本身来避免强制转换和 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;
}
检查
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))]