views:

72

answers:

3

I am wondering if it is a good idea or bad, placing things like a List of countries in ViewModel, for binding to a drop down list? For example on a site's Registration page.

I was under the impression that a ViewModel is supposed to represent an instance of the filled out form, but I think I may be wrong as I have seen other people put things like lists in their ViewModel.

Would it not be better to put it in a static class somewhere and called directly from the View?

Like CommonData.ListCountries(); and then using Lambda to convert to SelectList item list in the view Directly?

A: 

ViewModel = A class which is almost a model to the view.

i.e. You are creating almost duplicate of the your model but this model is having all those necessary properties and methods which are used by the view.

Like in your case : Since your View consist of a dropdown which requires a Enumarable collection of countries so it's perfectly valid to put this property in the viewmodel.

Creating a static class for a view which returns a collection violates the pattern.

saurabh
Well, but presumably you are going to use this kind of list elsewhere. So, you would be creating a property in every ViewModel for this list.
BobbyShaftoe
that's the whole idea of this pattern , you are putting everything in VM which is one to one with your Viewmodel , additionally you can create a parent VM where you can put all the repeated stuff.
saurabh
A: 

Whatever data your View needs, put it in the ViewModel.

The way i see it, once your view is going through the rendering process, it should have all the info it needs from the Model it is bound to.

If you start to use helper methods, then the View is "going back to the controller" in a sense. Extension/helper methods are fine for formatting, etc, but they should not call through the model.

Don't forget, you also have ViewData (basically HttpContext.Current.Items, lives for single request), which is a lightweight storage mechanism that can be used to share data across partial views (for example).

RPM1984
ok, so how do i handle the case where there are validation errors in the form and the ViewModel needs to be passed back into the original action to display the parially filled form, I would need to fetch the List again from the database. In that is it a good idea to add a Populate method on the view model to re-populate these drop down lists before passing it back to the view so i am not populating dropdown lists in two places?
sylon
No, that is not a good idea. ViewModel's should be simple storage mechanisms to hold onto data, not retrieve it. It should have nothing but properties (generally speaking). Remember, this is not Web Forms. There is no ViewState, your requests should be stateless. If after you submit your form you need some data again, `go get it again`, and just set the value into the ViewModel. Validation errors should be handled by model state. Take a look at some of the vids/tutorials on www.asp.net/mvc
RPM1984
Even better than refetching the data is doing AJAX form posts and letting the client (eg Javascript) decide where to redirect the page after a success or error message is returned.
Ryan
@Ryan - absolutely. Just don't "call back to a helper method".
RPM1984
A: 

As you've realized there are a variety of ways to accomplish your goal. While the MVC design pattern encourages certain application organizations how you organize your models, views and controllers is ultimately a matter of preference.

Scott Allen discusses his preference for dealing with ASP.NET MVC drop down lists in a blog post. Scott uses an extension method to convert an enumerable of a complex type into an IEnumerable<SelectListItem> on his model. He then describes that upon post back ASP.NET MVC will not be returning the IEnumerable<SelectListItem> he sent to the view, but only the value the user selected. He then suggests that utilizing two models can simplify things.

This is a reasonable description of what I refer to as ViewModels and FormModels. A ViewModel carries the display data to the view and a FormModel is used for carrying collected data back to a controller action. To explain further:

  • ViewModels contain data that help render views. By organizing my ViewModels this way I can place all necessary information to render a particular view into an associated model. This prevents me from having to use ViewData for anything that's not truly temporary.
  • FormModels are used to gather user input. FormModels (almost) never contain references to other complex types and are made up of primitives, DateTimes, and strings.

In either case I have a hard rule to never reuse a model for a different view. Having your models closely aligned with the views used to render them makes your views easier to write. You don't have to worry about things like static methods because your models should be carrying data to their associated views in a form that is easy for them to render. Tools like AutoMapper can help "flatten" domain objects into models for display purposes.

For additional reading checkout: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?

ahsteele
Thanks for the explanation. But, if i am not using AJAX what is the cleanest way of showing errors on the form and re-binding the drop down lists? I can't really create a new instance of my view model because it contains a partially filled form, but I still need to re-create the list of countries to pass back to the view the second time.
sylon