Сообщения об ошибках для проверки модели с использованием аннотаций данных

Учитывая следующие классы:

using System.ComponentModel.DataAnnotations;

public class Book{
   public Contact PrimaryContact{get; set;}
   public Contact SecondaryContact{get; set;}

   [Required(ErrorMessage="Book name is required")]
   public string Name{get; set;}
}
public class Contact{
    [Required(ErrorMessage="Name is required")]
    public string Name{get; set;}
}

Есть ли чистый способ предоставить отдельное сообщение об ошибке для каждого экземпляра Contact в книге с помощью DataAnnotations? Например, если имя отсутствует в экземпляре PrimaryContact, ошибка будет читать "первичный необходимо указать имя контакта".

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

Ответы

Ответ 1

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

public class Book
{
    public PrimaryContact PrimaryContact { get; set; }
    public SecondaryContact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }
}

public class Contact
{
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

[MetadataType(typeof(PrimaryContactMD))]
public class PrimaryContact : Contact
{
    class PrimaryContactMD
    {
        [Required(ErrorMessage = "Primary Contact Name is required")]
        public string Name { get; set; }
    }
}

[MetadataType(typeof(SecondaryContactMD))]
public class SecondaryContact : Contact
{
    class SecondaryContactMD
    {
        [Required(ErrorMessage = "Secondary Contact Name is required")]
        public string Name { get; set; }
    }
}

Ответ 2

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

CustomValidation позволит вам более подробно настроить ваши сообщения проверки на свойство, которое вы проверяете. Я использовал context.DisplayName для динамического отображения имени проверяемого свойства только для краткости, но это может быть дополнительно настроено на основе ваших потребностей.

Если требуется еще одна настройка, вы можете написать разные обработчики CustomValidation для каждого отдельного свойства, а не просто повторять то же, что и в моем примере кода.

using System.ComponentModel.DataAnnotations;

public class Book {
    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact PrimaryContact { get; set; }

    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }

    public static ValidationResult ValidateContact(Contact contact, ValidationContext context) {
        ValidationResult result = null;

        if (contact == null) {
            result = new ValidationResult(string.Format("{0} is required.", context.DisplayName));
        } else if (string.IsNullOrWhiteSpace(contact.Name)) {
            result = new ValidationResult(string.Format("{0} name is required.", context.DisplayName));
        }

        return result;
    }
}

public class Contact {
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

Ответ 3

Я также ищу ответ на этот вопрос, что я нашел до сих пор, если вы что-то вроде: "{0}" Контактное имя требуется "в сообщении об ошибке, оно автоматически заменит имя переменной. Я считаю, что есть способ явно использовать эту функцию.