Ошибки валидации на уровне свойств препятствуют валидации валидации на уровне класса - PullRequest
6 голосов
/ 23 июня 2010

Обновление после присуждения награды

Новое решение подходит к этой проблеме. Пожалуйста, обратитесь к ASP.NET MVC 3 Preview 1 здесь: http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx

Посмотрите в разделе Улучшения проверки моделей , где вы найдете решение моей проблемы.


Исходное сообщение

Ссылаясь на мой предыдущий пост Как проверить два свойства с ASP.NET MVC 2 , где я спросил, как я могу сравнить два свойства для проверки модели.

Я нашел ответ полезным, но у меня осталась совершенно другая проблема:

Проблема : Если атрибут ValidationAttribute уровня свойства содержит ошибку, то атрибуты ValidationAttribute уровня класса НЕ проверяются.

Пожалуйста, примите во внимание следующее:

[EqualTo("Email", "EmailConfirm", ErrorMessage = "E-mailadresserne skal være ens")]
[EqualTo("Password", "PasswordConfirm", ErrorMessage = "Adgangskoderne skal være ens")]
[Bind(Exclude="UserId")]
public class EditSiteUser
{
    [Required(ErrorMessage="Du skal bekræfte adgangskode")]
    public string PasswordConfirm { get; set; }

    [Required(ErrorMessage="Du skal bekræfte e-mailadressen")]
    [Email(ErrorMessage="Ugyldig e-mailadresse")]
    public string EmailConfirm { get; set; }
    public int UserId { get; set; }

    [Required(ErrorMessage = "Du skal indtaste et brugernavn")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en adgangskode")]
    public string Password { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en e-mailadresse")]
    [Email(ErrorMessage = "Ugyldig e-mailadresse")]
    public string Email { get; set; }
}

Здесь у меня есть две аттрибуты уровня класса, которые проверяют EmailConfirm и PasswordConfirm.

Если поле, такое как Имя пользователя, пусто и, следовательно, выдает ошибку, тогда два Атрибута EqualTo никогда не проверяются.

У кого-нибудь есть предложения по преодолению этой проблемы?

РЕДАКТИРОВАТЬ: Если вам нужна дополнительная информация об этой проблеме, пожалуйста, спросите в комментариях, и я буду очень рад предоставить вам любую дополнительную информацию, вам нужно.

Вопросы:

В: «Почему важно, чтобы проверки на уровне класса были проверены, если проверка на уровне свойств не удалась?».

A: «Потому что это часть формы, где пользователь вводит информацию в форму, которая отправляет обратно через AJAX. Когда форма возвращается, она должна показывать все текущие проблемы».

В: «Что именно является атрибутом EqualTo, который вы поместили в класс? Это пользовательский атрибут проверки? Если да, то как он работает? Что он делает?»

A: EqualTo является атрибутом ValidationAttribute уровня класса, который сравнивает значение двух свойств экземпляра класса. Найдите «PropertiesMustMatchAttribute» для аналогичной реализации.

Ответы [ 3 ]

6 голосов
/ 28 июня 2010

Это не поддерживается.Если какая-либо из проверок на уровне свойств завершится неудачно, проверки на уровне класса не будут выполнены.Я предлагаю вам взглянуть на MVC Foalproof Validation .Он расширяет проверку MVC, добавляя поддержку для проверки условных свойств.Я думаю, что это решило бы проблему для этого конкретного случая.

Сайт проекта утверждает, что он не работает с MVC2 RC, поэтому вам придется скачать исходный код и запустить его / принятьидеи сами.

1 голос
/ 27 января 2015

Чтобы развернуть ссылку на статью Скотта Гатри , начиная с MVC 3, вы можете выполнить проверку на уровне класса, реализовав интерфейс IValidatableObject.

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

Для вашего класса исключите атрибуты уровня класса и добавьте метод с именем Validate, например:

public class EditSiteUser : IValidatableObject
{
    public int UserId { get; set; }

    [Required(ErrorMessage = "Du skal indtaste et brugernavn")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en adgangskode")]
    public string Password { get; set; }

    [Required(ErrorMessage="Du skal bekræfte adgangskode")]
    public string PasswordConfirm { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en e-mailadresse")]
    [Email(ErrorMessage = "Ugyldig e-mailadresse")]
    public string Email { get; set; }

    [Required(ErrorMessage="Du skal bekræfte e-mailadressen")]
    [Email(ErrorMessage="Ugyldig e-mailadresse")]
    public string EmailConfirm { get; set; }


    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    { 
      // put whatever class level validation you want here

      if (Email !== EmailConfirm)
      {
          yield return new ValidationResult("E-mailadresserne skal være ens", new[] {"EmailConfirm"})
      }

      if (Password !== PasswordConfirm)
      {
          yield return new ValidationResult("Adgangskoderne skal være ens", new[] {"PasswordConfirm"})
      }
    }

}

Вы можете продолжить yield return столько сообщений проверки, сколько захотите.

И вы можете отобразить их все на клиенте с помощью @Html.ValidationSummary

Если вы хотите, чтобы сообщение отображалось рядом с определенным элементом управления, ValidationResult*Конструктор 1024 * принимает перегрузку с memberNames затронутых свойств, и вы можете предоставить сообщение проверки для этого конкретного свойства с помощью ValidationMessageFor HTML-помощника, например:

@Html.ValidationMessageFor(Function(model) model.TestOne )

Также стоит упомянуть, что вы можете использовать CompareValidator, чтобы легко гарантировать, что значения двух разных свойств равны.Преимущество использования этой аннотации в том, что она автоматически знает, как применить это на клиенте и на сервере, тогда как добавление IValidatableObject будет выполняться только на сервере.

[DataType(DataType.Password)]
public string Password { get; set; }

[Compare("Password")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }

Для дальнейшего использованиячитая, Скотт Гатри еще один пост с более подробной информацией о проверка на уровне класса .

0 голосов
/ 05 июля 2010

Из вашего примера, что вы хотели бы иметь поля «Подтверждение ввода другого поля ввода», правильная реализация будет

 [EqualTo("Email", ErrorMessage = "E-mailadresserne skal være ens")]
 public string EmailConfirm { get; set; }

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

это возвращает конфигурацию проверки обратно в свойство и решает вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...