Fetching data within an ASP.NET MVC ViewModel class?

asp.net-mvc

Solution

I encountered the same issue. I started creating classes for each action when the code got too big for the action methods. Yes you will have some data retrieval in classes and some in the controller methods. The alternative is to have all the data retrieval in classes, but half the classes you won't really need, they will have been created for consistency sake or have all the data retrieval in the controller methods, but again, some of those methods will be too complex and needed to have been abstracted into classes... so pick your poison. I would rather have a little inconsistency and have the right solution for the job.

As for putting behavior into the ViewModel, I don't, the point of the ViewModel is to be a thin class for setting and extracting values from the View.

There have been cases where I've put conversion methods in the ViewModel. For instance I need to convert the ViewModel to the corresponding entity or I need to load the ViewModel with data from the Entity.

To answer your question, I prefer to retrieve data from with in the controller/action methods.

Typically with DropDowns, I create a dropdown service. DropDowns tend to be the same data that spans views. With the dropdowns in a service I can use them on other views and/or Cache them.

Depending on the layout, 40 plus fields could create a cluttered view. Depending the type of data, I would try to span that many fields across multiple views with some sort of tabbed or wizard interface.

Problem

For those that create ViewModels (for use by typed views) in ASP.NET MVC, do you prefer to fetch the data from a service/repository from within the ViewModel, or the controller classes? For example, we started by having ViewModels essentially being DTOs and allowing our Controllers to fetch the data (grossly oversimplified example assumes that the user can only change employee name): ``` public class EmployeeViewModel { public String Name; //posted back public int Num; //posted back public IEnumerable<Dependent> Dependents; //static public IEnumerable<Spouse> Spouses; //static } public class EmployeeController() { ... public ActionResult Employee(int empNum) { Models.EmployeeViewModel model = new Models.EmployeeViewModel(); model.Name = _empSvc.FetchEmployee(empNum).Name; model.Num = empNum; model.Dependents = _peopleSvc.FetchDependentsForView(empNum); model.Spouses = _peopleSvc.FetchDependentsForView(empNum); return View(model); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult Employee(Models.EmployeeViewModel model) { if (!_empSvc.ValidateAndSaveName(model.Num, model.Name)) { model.Dependents = _peopleSvc.FetchDependentsForView(model.Num); model.Spouses = _peopleSvc.FetchDependentsForView(model.Num); return View(model); } this.RedirectToAction(c => c.Index()); } } ``` This all seemed fine until we started creating large views (40+ fields) with many drop downs and such. Since the screens would have a GET and POST action (with POST returning a view if there was a validation error), we'd be duplicating code and making ViewModels larger than they probably should be. I'm thinking the alternative would be to Fetch the data via the Service within the ViewModel. My concern is that we'd then have some data populated from the ViewModel and some from the Controller (e.g. in the example above, Name would be populated from the Controller since it is a posted value, while Dependents and Spouses would be populated via some type of GetStaticData() function in the ViewModel). Thoughts?

Original source