Как DataAnnotations действительно работает в MVC? - PullRequest
13 голосов
/ 01 марта 2011

Это скорее теоретический вопрос.

В настоящее время я проверяю проверку MVC 3 с помощью ComponentModel.DataAnnotations, и все работает автоматически, особенно на стороне клиента.

Как-то что-топроверяет эти атрибуты и генерирует JavaScript для проверки (или атрибуты html5, если используется ненавязчивый режим), и это работает.

Мой вопрос заключается в том, что генерирует JavaScript на стороне клиента, и как я могу получить к нему доступ и изменить его.?Например, я хочу обрабатывать данные атрибуты dataannotation немного по-другому или обрабатывать пользовательские атрибуты (я обнаружил, что могу выводить их из ValidationAttribute, но, возможно, по какой-то причине я не хочу).

Может кто-нибудь объяснить мне, что на самом деле происходит?(Или ссылки на хорошие объяснения также были бы хорошими, поскольку я нашел только учебные пособия для фактического использования аннотаций данных)

РЕДАКТИРОВАТЬ: Также с производным от ValidationAttribute, проверка на стороне клиента не работает автоматически.Почему?

1 Ответ

15 голосов
/ 01 марта 2011

MVC3 имеет новый механизм проверки jQuery, который связывает метаданные атрибутов проверки и проверки jQuery. Это файл jquery.validate.unobtrusive, который принимает все атрибуты data- и работает с ними, как и раньше, когда вы устанавливаете

* 1004.*

Все, что вам нужно сделать, - это создать собственные Настраиваемые атрибуты проверки , для этого у вас есть 2 варианта:

  • Создать Настраиваемый атрибут проверки , который наследует интерфейс ValidationAttribute и переопределяет IsValid

или

  • Создайте Самопроверченную модель , используйте модель IValidatebleObject все, что вам нужно, это вернуть Validate метод

в MVC3 , теперь у вас есть метод, который вы можете переопределить, который имеет объект ValidationContext, где вы можетепросто получите все ссылки, свойства и значения любого другого объекта в форме

Создайте свой собственный, и этот ненавязчивый файл будет обрабатывать отображение того, что нужно вашему пользовательскому валидатору, и будет работать вместе с jQuery.Плагин валидации.

ВЫ НЕ ИЗМЕНЯЕТЕ javascript ... это sooo 90's, а не MVC!

например, если вы хотите проверить, скажем, 2 датычто последнее не может быть меньше первого (например, период времени)

public class TimeCard
{
    public DateTime StartDate { get; set; }

    [GreaterThanDateAttribute("StartDate")]
    public DateTime EndDate { get; set; }
}

, создавая Пользовательскую проверку

public class GreaterThanDateAttribute : ValidationAttribute
{
    public string GreaterThanDateAttribute(string otherPropertyName)
        :base("{0} must be greater than {1}")
    {
        OtherPropertyName = otherPropertyName;
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(ErrorMessageString, name, OtherPropertyName);
    }

    public override ValidateionResult IsValid(object value, ValidationContext validationContext)
    {
        var otherPropertyInfo = validationContext.ObjectTYpe.GetProperty(OtherPropertyName);
        var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
        var thisDate = (DateTime)value;

        if( thisDate <= otherDate )
        {
            var message = FormatErrorMessage(validationContext.DisplayName);
            return new ValidationResult(message);
        }

        return null;        
    }    
}

при использовании Самостоятельная проверка модель, тогда код будет просто

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if( EndDate <= StartDate )
        yield return new ValidationResult("EndDate must be grater than StartDate");
}

Имейте в виду, что пользовательская проверка является универсальной, поэтому большая часть кода и Самостоятельная проверка работают только на применяемой модели.

Надеюсь, это поможет


добавлено

Я не объяснил Пользовательская проверка клиента часть, не стесняйтесь спрашивать, нужны ли вам примеры, но в основном:

В MVC3 проще (если, конечно, вы понимаете jQuery.Validate), все, что вам нужно сделать, это:

  • Реализация IClientValidateble
  • Реализация метода проверки jQuery
  • Реализация ненавязчивого адаптера

Чтобы создать эти 3 вещи, давайте учтем это GreaterThanDateAttribute и создадим пользовательскую проверку на стороне клиента.Для этого нам нужно закодировать это:

и добавить GreaterThanDateAttribute

public IEnumerable<ModelCLientValidation> GetCLientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    var rule = new ModelCLientValidationRule();
    rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
    rule.ValidationType = "greater"; // This is what the jQuery.Validation expects
    rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter

    yield return rule;
}

Затем вам нужно написать новый jQuery Validator и метаданные адаптер , который свяжет jQuery.Validation с вашим кодом, предоставив правильные атрибуты data- для этого поля (если, конечно, UnobtrusiveJavaScriptEnabled имеет значение true)

создайте новый файл js и прикрепитек вашему <head> например как

<script src="@Url.Content("~/Scripts/customValidation.js")" type="text/javascript"></script>

и добавьте новую проверку

jQuery.validator.addMethod("greater", function(value, element, param) {
    // we need to take value and compare with the value in 2nd parameter that is hold in param
    return Date.parse(value) > Date.parse($(param).val());
});

, а затем мы напишем адаптер

jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) {
    // pass the 'other' property value to the jQuery Validator
    options.rules["greater"] = "#" + options.param.other;
    // when this rule fails, show message that comes from ErrorMessage
    options.messages["greater"] = options.message;
});
...