3

For example I have the Models: Student and Course. Student has a List<Course> Courses{get;set;}

All data is already populated from the web service

I have a Student/Index which returns an ActionResult that takes a StudentViewModel But I also have a Course/Index View which returns an ActionResult takes a CourseViewModel

That should set the foundation for my question: Is it alright if I follow this option, which I think is very neat and simple: Create an instance of a ViewModel in the Student/Index View

 @foreach(var course in Model.Courses)
    {
       Html.RenderPartial("path/tocourse", 
        new CourseViewModel{Course = course}) ;
    }

Or should I make StudentViewModel have a List<CourseViewModel>, so I can have:

@foreach(var courseViewModel in Model.CourseViewModels)
{
       Html.RenderPartial("path/tocourse", courseviewModel) ;
}

At first glance, the above might look better, but in the Index action (or whatever) it would require me to do the following:

 new StudentViewModel{
            CourseViewModels = courses.Select(c=>new CourseViewModel{copy stuff}).ToList()
       } 

I hate that, and also it could confuse me later on or another developer, seeing that another indirection gives me access to Courses i.e StudentViewModel.StudentModel.Courses.

So which one is better approach? Surely it can't be that bad to create an instance of a ViewModel or a Model for that matter in a View?

Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • 3
    FWIW I usually add a layer in the middle to "compose" more complex view models to avoid the mess in the controllers and/or repeating logic (see my answer here http://stackoverflow.com/a/14132184/453277). – Tim M. Feb 11 '13 at 23:25
  • @TimMedora Your answer introduces a lot of terminology I need to read about.. Composers? :P – Lews Therin Feb 11 '13 at 23:33
  • This feels like a question better suited to http://programmers.stackexchange.com/ - I don't think there's a canonical answer for "is it OK..." – Tieson T. Feb 11 '13 at 23:35

2 Answers2

4

It's perfectly OK to do this. It's not considered Best Practice. Best Practice would be to do as little processing or instantiation as possible in your View.

For the sake of SOC, I would re-factor this code to use Partials with Child Action Methods

Html.Action("path/tocourse");

The Child Action will instantiate and pass the Model, lightening your View.

[ChildActionOnly]
public ActionResult tocourse()
{

courseviewModel model = new courseviewModel();

    return PartialView(model);
}
Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
  • SOC? What is that? Eh, that would me to fetch the data separately.. I kind of need it together. – Lews Therin Feb 11 '13 at 23:22
  • Separataion Of concerns: meaning do as little in your View as Possible. Count on your Controller to do the heavy lifting. This is considered Best Practice. But like all such guidelines, theyre not religion, just consideration. I believe situations vary. – Dave Alperovich Feb 11 '13 at 23:24
  • 1
    Oh yeah I know what SoC is. It just didn't click :S. – Lews Therin Feb 11 '13 at 23:25
  • Still not sure if that would work properly.. As said, the Student class is modeled to encapsulate List, if I was to give another programmer wouldn't they expect the whole data at once? – Lews Therin Feb 11 '13 at 23:26
  • Ahhh, my implementation was sloppy. You WOULD have to pass the course object to implement my way. And TO BE HONEST, your way is 'neat' and would work. I'm partial to my way, and it follows 'Best Practices' guidelines of NOT instantiating in View. But again, nothing wrong with your approach. – Dave Alperovich Feb 11 '13 at 23:31
  • Np, I'm going to wait a few more minutes for suggestions.. if no more contributions, I will accept your answer. Thanks for the quick reply btw. – Lews Therin Feb 11 '13 at 23:42
0

Ideally your view should not have any viewmodel instance logic rather the controller should do all that stuff and give that model to the view. View should be clean. And viewmodel should only have those properties that you need for the view. Now, you can have a model that is complex enough but if you find yourself that a particular model is very complex for your view, just make a viewmodel specific to that view with limited properties that your view needs.

KKS
  • 3,600
  • 1
  • 27
  • 54