Как сохранить валидацию СУХОЙ?
Используя этот подход для просмотра моделей в MVC: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
оставляет в ответе оставшийся без ответа вопрос. Так что пришло время, когда я его прояснил.
Если я использую auto mapper для сопоставления свойств домена с dto, то я понимаю, что мой доменный уровень может вернуть набор правил проверки, когда dto сопоставляется с объектом домена, который сохраняется.
Но я не вижу DRY способ получения проверки клиента для работы и добавления ошибок в состояние модели, чтобы они соответствовали правильное свойство в модели представления.
Приветствия
Ответы
Ответ 1
Я нашел связанный вопрос с некоторыми интересными ответами:
Атрибуты проверки отображения из домена в DTO
Я думал об этом, и в некотором роде он аналогичен ситуации, которую мы имеем с проверкой на стороне сервера и на стороне клиента. (например, с использованием как NHibernate Validator, так и jQuery.validate).
В эти дни довольно хорошо принято, что у вас должен быть полный набор проверки на стороне сервера, а добавление проверки на стороне клиента - это вариант, который вы можете выбрать, чтобы сделать ваше приложение более удобным для пользователя. Раньше было, что вы должны вручную выполнить проверку на стороне клиента, но вы приняли дублирование работы из-за преимущества в удобстве использования.
Я бы сказал, что то, с чем мы имеем дело, очень похоже. У вас должна проверка на уровне домена. Вы не можете полагаться на приложения-потребители, чтобы всегда добавлять подтверждение.
Затем у вас есть опция в приложении добавления проверки на модели DTO/view. Вы делаете это, потому что более полезно обрабатывать ошибки проверки в представлении, а не пропускать их до домена, который может генерировать исключение или давать менее полезное сообщение об ошибке. Дело в том, что с точки зрения домена вы не полагаетесь на это. Вы по-прежнему уверены в своей системе, потому что знаете, не прошли ли какие-либо плохие данные, ваша модель поймает ее.
Случай с клиентом и сервером в наши дни не является проблемой, потому что для его автоматизации сделано много работы, создавая клиентский код из кода на стороне сервера (например, ModelValidatorProvider в ASP.Net MVC). Я считаю, что по мере того, как все больше и больше людей начинают использовать модели представлений /DTO, мы начнем видеть аналогичные решения для корректного отображения проверки домена на DTO (это уже происходит с AutoMapper).
Короче говоря, мой (прагматичный, а не идеальный;)) ответ:
Принять нарушение DRY на данный момент, провести валидацию в обоих местах и попытаться внести вклад в проекты, целью которых является автоматизация в будущем
Ответ 2
Я предпочитаю помещать модель как свойство в ViewModel вместе с другими полями, зависящими от вида. Таким образом, он проверяется MVC во время привязки, и я могу проверить его на бэкэнд, если он не связан через MVC. Таким образом, проверка клиента обеспечивается MVC, и я получаю чистые модели с объектом проверки, не связанным напрямую с представлением.
public class MyViewModel
{
public MyModel MyModel {get;set;}
public bool IsSomethingAllowed {get;set;}
}
public class MyModel
{
public int Id {get;set;}
[Required]
public string Name {get;set;}
}
Ответ 3
Общий подход заключается в том, чтобы поместить все ваши проверки в ваши модели просмотра, как правило, используя аннотации данных. MVC позволяет автоматически генерировать проверку на стороне клиента (javascript) из аннотаций данных. Довольно DRY.
Вы выполняете действия с контроллером в режиме просмотра и проверяете свойство IsValid. Таким образом, вы проверяете на клиенте и сервере один и тот же код (или должны указывать атрибуты в случае аннотаций данных):
[HttpPost]
public ActionResult ResetPassword(ResetPasswordViewModel viewModel)
{
if (ModelState.IsValid)
{
// convert to dto/entity and pass to next layer
// redirect to success page
return RedirectToAction("ResetPasswordSuccess");
}
// display original view which will display error messages
return View();
}
Просто добавлю, что только при наличии действия контроллера в представленииModel в качестве параметра привязка модели MVC по умолчанию автоматически проверяет вашу модель обзора и добавляет любые ошибки в коллекцию ошибок ModelState, которая используется для отображения ошибок в ваших представлениях.