14

Is it a better idea to have a single ViewModel per view or one per controller action?

Example:

public ProjectController : Controller
{
    public ActionResult Edit(int id)
    {
        var project = ...;

        return View(new ProjectEditViewModel(project));
    }

    [HttpPost]
    public ActionResult Edit(ProjectEditViewModel model)
    {
    }

    **OR**

    [HttpPost]
    public ActionResult Edit(Project model)
    {
    }

    [HttpPost]
    public ActionResult Edit(ProjectEditPostViewModel model)
    {
    }
}

Here are the three options, which is best?

  1. Use the same ViewModel for my POST/GET actions.
  2. Use a ViewModel for my GET action and my domain model for my POST action.
  3. Use a different ViewModel for GET and a different ViewModel for POST.
BigJump
  • 15,561
  • 3
  • 31
  • 29
Dismissile
  • 32,564
  • 38
  • 174
  • 263

4 Answers4

10

Using a different view model for the GET and POST actions is the best and most flexible design. But using the same view model for the GET and POST actions also works in 90% of the cases and it is fine a good design. So if using the same view model works in your scenario don't hesitate to reuse it like this.

In the case where different view models are used for the GET and POST actions there is still some relation between those classes: inheritance or composition.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • In general is it a bad idea to use your Domain model itself as the object that you are POSTing to your controller actions? In my example, if my Project class is an Entity Framework class, is it a bad idea to use that as the parameter of my POST controller action? – Dismissile Sep 13 '11 at 19:57
  • 2
    @Dismissile, very bad idea. Never use any domain model as input/output of any controller action and this under any circumstances. While there could be different opinions about the two approaches discussed here with view models, domain models are not even something that should ever be considered. You should always define view models, always. – Darin Dimitrov Sep 13 '11 at 19:58
  • Similar to what you said about never using a domain model as input/output of any controller action. If I created a ViewModel for Editing a Project and named it ProjectEditViewModel, would that ViewModel have a reference to a Project as one of its properties or would you create a ViewModel with all of the fields that need to be displayed and then use some sort of Mapping to get the fields from the Project to the ViewModel? – Dismissile Sep 13 '11 at 20:07
  • 1
    @Dismissile, I wouldn't reference any domain model as a property to a view model. I would include and repeat the properties I need in this particular view. – Darin Dimitrov Sep 13 '11 at 20:08
  • @DarinDimitrov: AD your "*You should always define view models, always*" I would rather define this: Always use a non-DAO class for user interaction. They may be view model entities, application model entities or anything else that translates to data model entities on the server. I usually have an `App.Objects` assembly with inter-layer communicating POCOs that are used all over the application and are transformed back and forth by repositories to data model entities. And when a view demans a strictly Asp.net MVC specific view model, that class is not part of the same assembly. – Robert Koritnik Oct 26 '11 at 10:25
3

The correct answer

Neither. There's no silver bullet and shouldn't be.

The correct answer is therefore: use as many view models as your user interface process demands. That's regardless of views or controller actions.

Sometimes an action demands a view, other a view. But don't follow some strict guidelines that would hinder your development. View models will come naturally as you develop your application. And should. Otherwise you may end up with unreasonable views that are based on some guideline you've set in stone.

This is actually a similar answer as @DarinDimitrov's, but with a direct conclusion.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
1

Use different model to receive input parameters in Post action (I don't even call it ViewModel in that case) than to pass output parameters to the view.

That way you can customize exactly what input parameters do you accept.

ggarber
  • 8,300
  • 5
  • 27
  • 32
0

I follow this approach for basic forms:

  • One view model for the GET
  • One view model for the POST

The GET model inherits the POST model.

I will often pass a domain object to the GET model's constructor, and do 2 things with it:

  1. Populate the POST model properties with data from the domain object.
  2. Encapsulate the domain object as a local variable in the GET model. I use this for displaying some (read-only) data from the domain object. Saves a bit of effort. Some people will tell you not to do this.
Chalky
  • 1,624
  • 18
  • 20
  • And inline with the other answers/comments here, I always have a model (or pair of get/post models) per view. – Chalky Jul 06 '15 at 00:35