В моем приложении MVC3 у меня есть класс «запросов», специфичный для каждого контроллера, который выполняет преобразования между сущностями домена и преобразует их для просмотра моделей. Я делаю это, чтобы поддерживать чистоту моих контроллеров, и проще проводить модульное тестирование контроллеров и запросов по отдельности.
Однако существуют случаи, когда метод запроса должен передавать неисключительные сообщения об ошибках в представление (например, объект не был найден). Однако, поскольку мой контроллер получает только ViewModel от метода запроса, а не код возврата любого типа, я обнаружил только две опции для передачи этой ошибки:
Выдать исключение из метода запроса и использовать блок Try / Catch, чтобы перехватить исключение в контроллере.
Добавьте свойство к модели представления с именем «ErrorMessage», которое заполняется методом запроса, который представление использует для выполнения логики отображаемых потребностей.
Поскольку это не исключительные случаи, и я знаю, что не следует использовать Try / Catch для управления потоком программы, я решил использовать второй метод. Хотя сейчас это работает, мне кажется, что это «грязно» по следующим причинам:
- Контроллер должен получать всю модель представления в случае возникновения ошибки только для того, чтобы получить свойство ErrorMessage.
- Представление должно иметь жестко запрограммированную логику и два раздела для отображения либо ошибки, либо нормального содержимого
- Хотя я мог бы добавить
if (Model.ErrorMessage != null)
логику в мой контроллер, чтобы определить, какой вид пройти, он все еще не выглядит как «чистое» решение.
Существуют ли какие-либо шаблоны проектирования, которые я мог бы использовать, чтобы помочь мне реорганизовать этот код и сделать его чище?
Пример представления модели:
public class ApplicationViewModel
{
public string ErrorMessage { get; set; }
public int Id { get; set; }
public string Name { get; set; }
// Other properties here...
}
Пример метода контроллера:
public ActionResult Retrieve(Guid guid)
{
return View("Application", _applicationQueries.GetApplicationViewModel(guid));
}
Пример метода ApplicationQueries:
public ApplicationViewModel GetApplicationViewModel(Guid guid)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
applicationViewModel.ErrorMessage = "The requested application does not exist.";
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
Фрагмент из Application.cshtml Представление для обработки ошибок:
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
if (Model.ErrorMessage != null)
{
<div>@Model.ErrorMessage</div>
}
else
{
<!-- Display "normal" content here //>
}