The very huge model is a business requirement, it has to be edited as one entity, preferably on one page, it makes perfect sense but I can't talk about it. I originally thought (or hoped) there was an easy to describe solution, but apparently, this isn't a common thing in MVC. It would be very different with AJAX, it has its pros and cons. For sure it's more widely used, hence more documented. Without AJAX, there is only one round-trip, which is a bit bigger, but it's a smoother user experience. Anyway, here's a rough guide how to do it the way I asked.
The client-server roundtrip is handled by MVC with (mostly) hidden fields as I said in the question. Later it can be optimized by encoding some stuff in JSON instead of hidden fields, it doesn't affect the rest of the system.
Normal fields are stored in normal editors, not hidden fields. It makes no difference from the perspective of the client-server roundtrip. So these can be edited in place.
Grid rendering is also easy. Server-side MVC grids are suboptimal in this case, because they would send redundant data to the client side. Luckily there are a lot more client-side grid solutions, they are by nature server platform independent. Just collect the required data from the hidden fields and use a JavaScript grid library to build a grid from it when the page loads. Naturally, as I said, the lists can contain lots of data and other nested lists, but in this simple grid, a few necessary columns must be selected, no problem with that.
Now comes the interesting part, how to edit a grid row with all that complex data. Let's say I have a list of Persons in my model, and they have a list of Addresses. There is a Person grid, and when you click on a row, you want the end user to be able to edit additional data for a Person and also his Addresses.
First of all, the Person editor template has to be sent to the client side in advance. We need to put that editor template inside our view, and hide it. Whenever the user wants to edit a person, we create a JS dialog with the contents of that editor template.
We need to bind the Person editor template to a Person object stored in the hidden fields. Based on which row the user clicked, we get an index, and we bind Model.Persons[index]
to that template. Knockout.js is a good candidate for JS binding. It does all the field copying back and forth.
An MVC editor template can also contain validation logic. It's no problem in this case, because we rendered the editor template to the client side as a whole. The validation will happen inside the popup window without any kind of magic. When the user presses the save button, validation will run, and when it succeeds, we use the binding engine to copy the popup contents back into the hidden fields.
It is not the simplest of things, but it is very straightforward. Actually, several different JS libraries are needed, not as I hoped. So if anyone wants to edit a complex model on a single page without AJAX, it is certainly possible. It's still not completely documented because I can't share more details. But it has its advantages: only one round-trip, hence faster user experience, and there's no need to maintain state on the server, all the data is retrieved and saved as one entity in one roundtrip.