views:

36

answers:

2

Just working through a tutorial on asp.net/mvc for the music store application.

Ref: http://www.asp.net/mvc/tutorials/mvc-music-store-part-3

In the controller they are passing a list of genres to the view model, I am just a beginner but I feel like it is the viewmodel's job to present the data in what ever format the view requires.

the tutorial code does this...

public ActionResult Index() 
{     
    // Retrieve list of Genres from database     
    var genres = from genre in storeDB.Genres select genre.Name;       

    // Set up our ViewModel     
    var viewModel = new StoreIndexViewModel()
    {         
        Genres = genres.ToList(),         
        NumberOfGenres = genres.Count()
    }; 

    // Return the view     
    return View(viewModel);
}

What I want to do is pass genres to the viewModel and inside the viewModel create the list as well as set the NumberOfGenres property. The way this is coded the controller has to know more about the view than it needs to.

can someone show me what my viewModel class would look like in order to use the ToList() and Count() methods on the genres property inside my viewModel ?

+1  A: 

I'm going to disagree with you. The controller knows nothing about the view, only the model. The view model, IMO, should be a simple container just as it is in the tutorial. It's the controller's job to fill up the container with data and pass it off to the view.

It's an open question whether the view model is as simple as it needs to be, i.e. you can easily derive the number of genres from the list of them so it's not really necessary to have it as a separate property. If you wanted to just have the list stored in the model, all you would have to do is invoke the Count() method in the view instead of doing it in the controller.

Not knowing the tutorial, I'm not sure whether they've done it this way in anticipation of adding paging to the model, however. If you did want to support paging in the model, then you would want the total count as a separate property since you'd only be passing part of the collection to the view.

tvanfosson
respectfully, why would I need another "simple container" when i already have that in the model? It's possible that I am not understanding viewModel as it pertains to asp.net MVC but I took it as more like a presenter for the view rather than just a container for the data that the view will access. I was actually thinking it was both the simple container as well as a presenter that handles the tasks of things like formatting dates, creating data formats such as a list from the query result etc. I have used MVC patterns in other platforms and I may need to get rid of some old habits.
JBeckton
Ok, after some research I get it. The main benefit of ViewModel are strongly typed classes vs. a string based dictionary.
JBeckton
@JBeckton - but you can strongly type a View with just the Model, you don't necessarily need a ViewModel for that, so not sure that's the main benefit.
UpTheCreek
@JBeckton, @UpTheCreek -- the main benefit is that the view model is specific to the data needed by the view whereas the model is specific to a domain entity in your application. The two are only rarely the same thing in a reasonably complex application. If you make the view strongly typed to your domain model, then you find yourself augmenting the view data dictionary with the ancillary data needed by the view. In MVC3 with dynamic ViewModel properties this might be acceptable -- haven't used it so I can't comment there -- but I suspect that there will still be impedance mismatches.
tvanfosson
+1  A: 

I may be wrong but you seem confused about how viewModel is constructed. The code is doing exactly what you described.

ToList() method returns the query's result that was written above as a List. Mind that it's not executed till ToList() is called.

After getting results from database, they are assigned to the properties in StoreIndexViewModel class.

If we write the code in another way it may be easier to understand

public ActionResult Index() 
{     
    // Retrieve list of Genres from database     
    var genres = from genre in storeDB.Genres select genre.Name;
    var genresList=genres.ToList();       

    // Set up our ViewModel     
    StoreIndexViewModel viewModel = new StoreIndexViewModel()
    viewModel.Genres=genresList;
    viewModel.NumberOfGenres=genresList.Count;

    // Return the view     
    return View(viewModel);
}

Update:

You don't generate the list in the ViewModel. You get them from the database. If you take look at the LINQ expression, it gets the genre names only. Later these results are assigned to the property of the class.

ViewModels are used to provide additional info to the View. Here it's used to show other genres only. It only uses the their names so users can browse them. I didn't check the tutorial but creating,deleting or editing genres need their own functions.

Ufuk Hacıoğulları
your not entirely wrong, I am somewhat confused but probably more about the job the viewModel is supposed to perform. What i wanted to do was let the viewModel handle producing a list rather than doing it in the controller and passing the list in to the viewModel.
JBeckton
See my update. I hope it makes it more clear.
Ufuk Hacıoğulları
Ok, after some research I get it. The main benefit of ViewModel are strongly typed classes vs. a string based dictionary.
JBeckton