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

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

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 в Book с помощью DataAnnotations? Например, если имя отсутствовало в экземпляре PrimaryContact, ошибка будет гласить: «Требуется основное имя контактного лица».

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


person IaCoder    schedule 11.05.2010    source источник


Ответы (4)


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

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; }
    }
}
person Jab    schedule 11.05.2010

Вы можете рассмотреть возможность использования атрибута 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($"{context.DisplayName} is required.");
        } else if (string.IsNullOrWhiteSpace(contact.Name)) {
            result = new ValidationResult($"{context.DisplayName} name is required.");
        }

        return result;
    }
}

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

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

person Chris Stephens    schedule 12.11.2012

Код ниже в С# для форматирования ошибок аннотаций данных и форматирования в формате добавления в одной строке

  public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                if (actionContext.ModelState.IsValid) return;
                string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));
            }
        }
    }
person Kailash Mali    schedule 18.02.2021
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также предоставьте объяснение того, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением, как правило, более полезны и качественны, и с большей вероятностью привлекут положительные голоса. - person Ran Marciano; 18.02.2021