Повторное заполнение вложенных ViewModels после сбоя проверки - PullRequest
2 голосов
/ 10 января 2012

У нас есть модели представлений, в которых есть другие модели представлений. Например, у меня есть модель вида навигации практически под любой другой моделью вида, поскольку на каждом экране есть навигация. Логика построения модели навигационного представления находится в одном месте.

Проблема в том, что ссылочные типы, такие как модели представлений, обнуляются во время POST. Это имеет смысл, но это означает, что мы должны частично перестроить модели представления, если нам когда-либо понадобится вернуться к представлению снова, например, когда проверка не пройдена. Мы не можем просто перестроить модели представления с нуля, так как они содержат частично введенные данные.

Сейчас мы вручную проверяем ModelState.IsValid и вручную перестраиваем каждую дочернюю модель представления. Мы устраняем дублирование логики, создавая типы, называемые построителями, которые создают наши модели представлений. Эти компоновщики в настоящее время имеют три метода компоновки: один для построения модели пустого представления, один для обработки вопросов проверки и один для обработки редактирования.

ViewModel Build(<params>) // create
void Build(ViewModel, <params>) // validation error
ViewModel Build(DBObject, <params>) // edit

Это похоже на серьезное излишество. В 90% случаев, если свойство является другой моделью представления, его следует просто перестроить. Было бы неплохо, если бы существовала сторонняя библиотека, которая отображала бы модель представления в класс построителя, только создавая их по мере необходимости. Конечно, было бы рекурсивно и создавать модели дочерних представлений. Вместо:

return View(viewModel) 

или

return RedirectToAction("index", "home", viewModel) 

будут просто помощники вроде:

return View<ViewModel>()

или

return RedirectToAction<ViewModel>("index", "home")

1 Ответ

3 голосов
/ 10 января 2012

Например, у меня есть модель вида навигации почти для любой другой модели вида, поскольку у каждого экрана есть навигация.Логика построения модели представления навигации находится в одном месте.

Это кажется хорошим кандидатом для разделения моделей представления и использования помощника Html.Action для визуализации вашей навигации.меню из отдельного дочернего действия.

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

Таким образом, идея заключается в том, что у вас может быть контроллер меню, отвечающий за генерациюmenu:

public class MenuController: Controller
{
    private readonly IMenuRepository _repository;
    public MenuController(IMenuRepository repository)
    {
        _repository = repository;
    }

    [ChildActionOnly]
    public ActionResult Index()
    {
        var menu = _repository.GetMenu();
        var menuViewModel = Mapper.Map<Menu, MenuViewModel>(menu); // AutoMapper example
        return View(menuViewModel);
    }
}

, затем соответствующий индексный вид, который будет частичным, содержащим только разметку меню:

@model MenuViewModel
@{
    Layout = null;
}
<ul>
   <li>....
   <li>....
</ul>

, и затем вы можете отобразить меню внутри _Layout в определенном месте:

@Html.Action("index", "menu")

Тогда вы можете иметь контроллеры и просматривать модели, которые полностью не связаны с этим рендерингом меню.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...