Подтвердить что ты не робот

Как DataAnnotations действительно работают в MVC?

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

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

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

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

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

EDIT: также с использованием ValidationAttribute проверка на стороне клиента не работает автоматически. Почему?

4b9b3361

Ответ 1

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

<add key="UnobtrusiveJavaScriptEnabled" value="false" />

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

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

или

  • Создайте Self Validate Model, используя модель IValidatebleObject, которая вам нужна, чтобы вернуть метод Validate

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

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

ВЫ НЕ ИЗМЕНЯЙТЕ javascript..., что sooo 90, а не способ 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;        
    }    
}

если использовать модель Self Validating, тогда код будет просто

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

Имейте в виду, что пользовательская проверка является общей, поэтому много кода и Self Validating Model работают только с применяемой моделью.

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


добавлен

Я не объяснил часть Custom Client Validation, не смог спросить, нужны ли вам примеры, но в основном:

В 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 истинно)

создайте новый файл 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;
});