Humidify ViewModels in ASP.NET MVC

I have a page consisting of many user controls. The viewing model for this page is quite complex.

public class ComplexViewModel { public ObjectA ObjectAProperty { get; set; } public List<Things> ListOfThings { get; set; } public List<ThingCategories> ListOfThingCategories { get; set; } public List<ThingTypes> ListOfThingTypes { get; set; } public List<ThingOptions> ListOfThingOptions { get; set; } public int ChosenThingCategoryId { get; set; } public int ChosenThingTypeId { get; set; } public int ChosenThingOptionId { get; set; } public OtherObject ObjectData { get; set; } } 

This page also has a PostModel that contains information for filtering, sorting, etc.

  public class SimplePostModel { public int ChosenThingCategoryId { get; set; } public int ChosenThingTypeId { get; set; } public int ChosenThingOptionId { get; set; } public int ChosenThingFilterTypeId { get; set; } public int ChosenThingSortTypeId { get; set; } public int ChosenThingOtherId { get; set; } public int ChosenThingMoreId { get; set; } public int ChosenThingOMGId { get; set; } } 

A simple PostModel is checked, and then the controller opens 3+ repositories that make several calls in each and builds a presentation model. At least my controller action has become quite large.

This is by far the most difficult page I've worked on, and it's hard for me to decide how to make it easier.

My first thought was to create a factory view model that, after checking the bindings, would call in the repository and return the ViewModel.

Then I thought about creating a custom mediation that would do a PostModel check and then humidify the ViewModel in one step.

So my question is: how do you moisten a complex presentation model?

And although I am writing this, I had the idea of ​​using Html.RenderAction and creating a model for each of the user controls that make up this beast of the page.

Update:

Repositories make calls in WCF services, the application is part of a larger SOA architecture.

+4
source share
1 answer

Some general tips. Data can be divided into several categories: system area, session area, request area.

System area data is data that should be presented to the user, but the same for each user. An example blog application would be a tag cloud or category list. I would say that this data should not pass through the controller or action, because it has nothing to do with user interaction. The view itself can call HtmlHelper (or LayoutDataHelper), which knows how to get (and preferably cache) this data.

Session area data can be processed using ActionFilters, which populate the fields in ViewData.Model. It is not directly related to action parameters. For example, username. I prefer the form attribute

 public class SessionDataFilter : ActionFilter { public override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext.Result is ViewResult) { var view = filterContext.Result as ViewResult; // hydrate session data on view.ViewData.Model } } } 

In the action, everything else that is the scope / specifics of the request should be filled. However, this does not mean that you need to have one massive action method. I would see how your ViewModels are composed. As you suggested, if you have controls that need to be populated, it is likely that the information in the ViewModel can be grouped into related sets. That way, you can have a ViewModel that simply composes other smaller view models ("partial view models"). I then decomposed the logic to populate each partial representation model (and any other complex logic) each into its own reusable and isolated method.

A similar abstraction is used when working with messages, although I will worry about the usability of pages that publish a lot of unrelated data. You should be able to use ActionFilters ( OnActionExecuting ) to analyze related sets of input data (and, if necessary, verify) and assign action parameters to them. I prefer binder filters for published data if the same data set is not sent in several actions, and the input data form is always the same.

Good luck.

+6
source

All Articles