#asp.net-mvc #validation #localization #business-logic
#asp.net-mvc #проверка #локализация #бизнес-логика
Вопрос:
С помощью аннотаций данных теперь легко локализовать сообщения об ошибках, используя файлы Resource.resx, например, такие:
public class Student
{
. . .
[Required(ErrorMessageResourceName ="Required",
ErrorMessageResourceType = typeof(StudentResources))]
[StringLength(16)]
[Display(Name = "FirstName", ResourceType = typeof(StudentResources))]
public string FirstName { get; set; }
. . .
}
Теперь, допустим, я хочу проверить, произвел ли студент уже платеж за данный месяц и год:
public bool CheckIfAlreadyPaid(Payment payment)
{
return repository.GetPayments().Any(p => p.StudentId == payment.StudentId amp;amp;
p.Month == payment.Month amp;amp;
p.Year == payment.Year);
}
Если он уже произвел платеж, я делаю следующее на уровне моих сервисов:
if (CheckIfAlreadyPaid(payment))
{
modelState.AddModelError("AlreadyPaid",
Resources.Views.Payment.PaymentCreateResources.AlreadyPaid);
}
Это работает, но я не уверен в том, что ссылаюсь на файл ресурсов внутри уровня сервисов.
Существует ли стандартный или лучший способ локализации сообщений об ошибках, которые не привязаны к свойствам модели (аннотации данных) — ошибкам, возникающим из правил бизнес-логики? Должен ли я по-прежнему добавлять эти ошибки в ModelStateDictionary?
Ответ №1:
Я согласен, я не думаю, что это должно быть на уровне сервиса. Похоже, что это можно либо поместить в пользовательский атрибут проверки данных, либо обработать каким-либо другим подходом на этом уровне (использование беглой проверки может быть хорошим вариантом). В любом случае, я думаю, пока проверка остается в самом приложении MVC, вам может быть удобно использовать файлы ресурсов для хранения сообщений.
Ответ №2:
Я сделал это по-другому. Service
Уровень используется для проверки, был ли уже произведен платеж. В моем Controller
я добавляю сообщение об ошибке проверки к объекту ModelState, передавая ему локализованный строковый ресурс. Теперь я чувствую себя более комфортно с этим подходом.
Вот код:
/// <summary>
/// Performs validation of business logic...
/// </summary>
/// <param name="payment"></param>
/// <returns></returns>
private bool ValidatePayment(Payment payment)
{
if (paymentService.IsPaymentMade(payment))
{
ModelState.AddModelError("AlreadyPaid", Localization.AlreadyPaid);
}
return ModelState.IsValid;
}
Редактировать:
В дополнение к моему ответу, я только сегодня обнаружил, что ValidationSummary @Html.ValidationSummary(true)
делает именно то, что я хочу:
Html.ValidationSummary
возвращает неупорядоченный список (элемент ul) сообщений проверки, которые находятся вModelStateDictionary
объекте, и необязательно отображает только ошибки уровня модели.
Я передаю true
, и он будет отображать только ошибки уровня модели (ошибки аннотации без данных) в сводке только в верхней части страницы. Это здорово, но только если это сработает … 🙂
Я столкнулся с проблемой, когда мои пользовательские сообщения об ошибках, не привязанные к свойствам модели, не появлялись при настройке ValidationSummary(true)
. Затем я поискал в Google и нашел этот пост. Я попробовал его решение, но оно не сработало. Затем я поискал еще немного и нашел эту ссылку в Google Books (Pro ASP.NET Платформа MVC 2 (автор Стивен Сандерсон).
Я попробовал то, что описано там, передав пустую строку в качестве ключа ( string.Empty
), и она выполнила свою работу.
if(paymentService.IsPaymentMade(payment))
{
ModelState.AddModelError(string.Empty, Localization.PaymentAlreadyCreated);
}