2010-09-24 118 views
0

我在我的應用程序中使用數據註釋屬性進行驗證,並且我想要一個RequiredAsSet屬性,這將需要用屬性裝飾的所有屬性都被填充,或者它們都不是。該集合不能被部分填充。「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

如果我明白問題的正確性,那麼執行此操作的方法是使用類級別驗證屬性。然後您可以訪問整個對象,並可以使用反射來訪問您希望的任何屬性。實例在驗證期間傳入。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
public class RequiredAsSetAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     var properties = TypeDescriptor.GetProperties(value); 
     ... 
    } 
}