tags:

views:

35

answers:

4

Very often I need to pass "complicated" data to my views: different database objects, classes etc. And I'm tired of creating dozens of classes-helpers like.

class StatsPageViewData
{
    public User User { get; set; }
    public Something Something { get; set }
    // blah blah
}

Of course I can't just use ViewData["something"], it's just not as comfortable.

So my question is, is there any way to make this process easier, to automate it somehow?

+1  A: 

Use a plugin such as ReSharper that help you create these helper classes.

Start by using the classes and properties. This will marked them as missing in the editor, you can then use the plugin to create classes and properties, making the creation of helper classes much faster than doing it the other way around.

svinto
A: 

Start of with a ViewModelBase and extend this if need be.

Duncan
+1  A: 

I think the model-per-view pattern is a best practice. You can try to use inheritance and composition to share model components where possible (keeping your code DRY), but I've only had limited success with even that. To make the transformation from your view model to your business model easier you might try something like AutoMapper. I'm too far into the only big project that would benefit from it to apply it, but it's on my radar for something to try to ease the process.

tvanfosson
A simple convention can greatly simplify AutoMapper usage; e.g. make view models to provide their mapping via static GetAutoMap() methods, that are invoked at startup via bootstrap code.
queen3
+1, can't agree more.
Darin Dimitrov
+1  A: 

View model should rarely be just a collection of domain classes. First of all, putting domain classes into view model is a big topic; many think that you shouldn't do that. Your view probably doesn't need full User instance but only a name. If you keep full User instance in the view model it hides real view model intention, makes it hard to re-use, and so on. You probably better have string UserName property that properly formats the name, instead of accessing User properties in the view and formatting it there.

That's a theory and no-one has to follow it; but it's good to keep in memory and try to achieve.

Second, your view models shouldn't be just collections of domain classes because they should provide view semantics - for example, validation attributes and additional presentation logic. You can have aggregate properties that provide select lists' data, formatting, and so on. Another example, the POST view models can have methods to convert raw form data to entities.

You should move some presentation logic from views and/or controller into view models - formatting, properties that are only needed by views, and so on. Controller should not convert entity collection into view model data collection - view model should do that. View should not convert format User into single name and address string - view model should.

By doing so, you won't be tired of making "view model" classes because they won't be dumb no more, and your work won't be dump and/or repetitive. The view model classes will be as important as other classes in your application.

queen3
I agree with everything you said. But sometimes you do need to pass things like integer arrays, where using ViewData would be very awkward. And you don't need any abstraction layers here.
Alex
I currently have 150 views in my project, and I do sometimes pass pass single object (array, entity, etc), but when view gets more complex, I always create a view model and never have any problem with it. This is not the "best practice" but is a good balance between good and simple. If I has many "clients" for a view I always create view model in first place; if view has to do too much formatting from entity to strings itself I create a view model. I almost do not have view models that are nothing but bunch of properties.
queen3