Проверка на основе другого поля? - PullRequest
3 голосов
/ 28 июня 2010

В ASP.NET MVC 2 у меня есть класс Linq to sql, который содержит ряд полей.Теперь одно из полей является обязательным, когда другое поле имеет определенное (перечислимое) значение.

Я зашел так далеко, что написал собственный проверочный атрибут, который может принимать перечисление в качестве атрибута, но яне могу сказать, например: EnumValue = this.OtherField

Как мне это сделать?

1 Ответ

5 голосов
/ 29 июня 2010

MVC2 поставляется с примером «PropertiesMustMatchAttribute», который показывает, как заставить DataAnnotations работать на вас, и он должен работать как в .NET 3.5, так и .NET 4.0. Этот пример кода выглядит следующим образом:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
public sealed class PropertiesMustMatchAttribute : ValidationAttribute 
{ 
    private const string _defaultErrorMessage = "'{0}' and '{1}' do not match."; 

    private readonly object _typeId = new object(); 

    public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty) 
        : base(_defaultErrorMessage) 
    { 
        OriginalProperty = originalProperty; 
        ConfirmProperty = confirmProperty; 
    } 

    public string ConfirmProperty 
    { 
        get; 
        private set; 
    } 

    public string OriginalProperty 
    { 
        get; 
        private set; 
    } 

    public override object TypeId 
    { 
        get 
        { 
            return _typeId; 
        } 
    } 

    public override string FormatErrorMessage(string name) 
    { 
        return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, 
            OriginalProperty, ConfirmProperty); 
    } 

    public override bool IsValid(object value) 
    { 
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); 
        // ignore case for the following
        object originalValue = properties.Find(OriginalProperty, true).GetValue(value); 
        object confirmValue = properties.Find(ConfirmProperty, true).GetValue(value); 
        return Object.Equals(originalValue, confirmValue); 
    } 
} 

Когда вы используете этот атрибут, а не помещаете его в свойство класса вашей модели, вы помещаете его в сам класс:

[PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")] 
public class ChangePasswordModel 
{ 
    public string NewPassword { get; set; } 
    public string ConfirmPassword { get; set; } 
} 

Когда IsValid вызывается для вашего пользовательского атрибута, ему передается весь экземпляр модели, чтобы вы могли таким образом получить значения зависимых свойств. Вы можете легко следовать этому шаблону, чтобы создать даже более общий атрибут сравнения.

...