我在我的应用程序中使用数据注释属性进行验证,并且我想要一个RequiredAsSet属性,这将要求填充所有使用该属性修饰的属性,或者不需要填充任何属性。该集合不能填充部分。
我认为一个聪明的方法就是这样:
public class RequiredAsSetAttribute : RequiredAttribute
{
/// <summary>
/// Initializes a new instance of the <see cref="RequiredAsSetAttribute"/> class.
/// </summary>
/// <param name="viewModel">The view model.</param>
public RequiredAsSetAttribute(IViewModel viewModel)
{
this.ViewModel = viewModel;
}
/// <summary>
/// Gets or sets the view model.
/// </summary>
/// <value>The view model.</value>
private IViewModel ViewModel { get; set; }
/// <summary>
/// Determines whether the specified value is valid.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if the specified value is valid; otherwise, <c>false</c>.
/// </returns>
public override bool IsValid(object value)
{
IEnumerable<PropertyInfo> properties = GetPropertiesWihRequiredAsSetAttribute();
bool aValueHasBeenEnteredInTheRequiredFieldSet = properties.Any(property => !string.IsNullOrEmpty(property.GetValue(this.ViewModel, null).ToString()));
if (aValueHasBeenEnteredInTheRequiredFieldSet)
{
return base.IsValid(value);
}
return true;
}
/// <summary>
/// Gets the properties with required as set attribute.
/// </summary>
/// <returns></returns>
private IEnumerable<PropertyInfo> GetPropertiesWithRequiredAsSetAttribute()
{
return this.ViewModel.GetType()
.GetProperties()
.Where(p => GetValidatorsFromProperty(p).Length != 0 && !GetValidatorsFromProperty(p).Any(x => x == this));
}
/// <summary>
/// Gets the validators from property.
/// </summary>
/// <param name="property">The property.</param>
/// <returns></returns>
private static RequiredAsSetAttribute[] GetValidatorsFromProperty(PropertyInfo property)
{
return (RequiredAsSetAttribute[])property.GetCustomAttributes(typeof(RequiredAsSetAttribute), true);
}
}
它基本上将我的视图模型作为构造函数参数,并使用反射来查找用RequiredAsSet属性修饰的其他属性,以检查是否输入了任何内容。
事实证明,这不是一个聪明的想法,因为你无法将实例传递给属性的构造函数。只有常量表达式,类型表达式或数组创建表达式,正如编译器有用地指出的那样。
还有另一种方法吗?
答案 0 :(得分:0)
如果我理解问题是正确的,那么执行此操作的方法是使用类级别验证属性。然后,您可以访问整个对象,并可以使用反射来访问您希望的任何属性。在验证期间传入实例。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class RequiredAsSetAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var properties = TypeDescriptor.GetProperties(value);
...
}
}