We have view models that have other view models in them. For instance, I have a navigation view model under just about every other view model, since every screen has navigation. The logic for building the navigation view model is in one place.
The problem is that reference types, like the view models, are null-ed out during POST-ing. This makes sense, but it means we have to partially rebuild the view models if we ever need to go back to the view again, such as when validation fails. We can’t just rebuild the view models from scratch since they hold partially entered data.
Right now, we are manually checking ModelState.IsValid and rebuild each child view model manually. We are eliminating duplicating logic by creating types called Builders that constructs our view models. These builders currently have three build methods: one for building a blank view model, one for handling validation issues and one for handling editing.
ViewModel Build(<params>) // create
void Build(ViewModel, <params>) // validation error
ViewModel Build(DBObject, <params>) // edit
This seems like major overkill. 90% of the time, if a property is another view model, it should just be rebuilt. It would be nice if there was a 3rd party library that would map a view model to a builder class, only constructing them on an as-needed basis. It would be recursive, of course, and build child view models, as well. Instead of:
return View(viewModel)
or
return RedirectToAction("index", "home", viewModel)
there would simply be helpers like:
return View<ViewModel>()
or
return RedirectToAction<ViewModel>("index", "home")
That seems like a great candidate for splitting your view models and using the Html.Action helper to render your navigation menu from a separate child action.
This way you no longer have to worry about the main action and view model.
So the idea is that you could have a menu controller responsible for generating the menu:
then the corresponding Index view which will be a partial containing only the menu markup:
and then you could render the menu inside your _Layout at its defined location:
Then you could have controllers and view models which are completely dissociated with this menu rendering.