Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices concerning view model and model updates with a subset of the fields

By picking MVC for developing our new site, I find myself in the midst of "best practices" being developed around me in apparent real time. Two weeks ago, NerdDinner was my guide but with the development of MVC 2, even it seems outdated. It's an thrilling experience and I feel privileged to be in close contact with intelligent programmers daily.

Right now I've stumbled upon an issue I can't seem to get a straight answer on - from all the blogs anyway - and I'd like to get some insight from the community. It's about Editing (read: Edit action). The bulk of material out there, tutorials and blogs, deal with creating and view the model. So while this question may not spell out a question, I hope to get some discussion going, contributing to my decision about the path of development I'm to take.

My model represents a user with several fields like name, address and email. All the names, in fact, on field each for first name, last name and middle name. The Details view displays all these fields but you can change only one set of fields at a time, for instance, your names. The user expands a form while the other fields are still visible above and below. So the form that is posted back contains a subset of the fields representing the model.

While this is appealing to us and our layout concerns, for various reasons, it is to be shunned by serious MVC-developers. I've been reading about some patterns and best practices and it seems that this is not in key with the paradigm of viewmodel == view. Or have I got it wrong?

Anyway, NerdDinner dictates using FormCollection och UpdateModel. All the null fields are happily ignored. Since then, the MVC-community has abandoned this approach to such a degree that a bug in MVC 2 was not discovered. UpdateModel does not work without a complete model in your formcollection.

The view model pattern receiving most praise seems to be Dedicated view model that contains a custom view model entity and is the only one that my design issue could be made compatible with. It entails a tedious amount of mapping, albeit lightened by the use of AutoMapper and the ideas of Jimmy Bogard, that may or may not be worthwhile. He also proposes a 1:1 relationship between view and view model.

In keeping with these design paradigms, I am to create a view and associated view for each of my expanding sets of fields. The view models would each be nearly identical, differing only in the fields which are read-only, the views also containing much repeated markup. This seems absurd to me. In future I may want to be able to display two, more or all sets of fields open simultaneously.

I will most attentively read the discussion I hope to spark. Many thanks in advance.

like image 892
Martin Avatar asked Jan 17 '10 20:01

Martin


People also ask

What should ViewModel contain?

View Model: It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model. The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind.

What are the responsibilities of a ViewModel?

ViewModel is a class that is responsible for preparing and managing the data for an Activity or a Fragment . It also handles the communication of the Activity / Fragment with the rest of the application (e.g. calling the business logic classes).

How do you pass ViewModel to view?

The View Models can be passed to the View by creating a dynamic property in ViewBag. It can be passed using the Model Property of the ViewData. The Model property allows us to create the strongly typed Views using the @model directive.

How do you define ViewModel?

In the Model-View-Controller pattern, the term Model refers to objects which represent the data in the application. Often, model objects correspond to tables in your database, but they don't have to. Controller action methods which return an ActionResult can pass a model object to the view.


2 Answers

I am doing it like this (the mapping is done automatically inside modelBuilder with the ValueInjecter):

I have a sample asp.net-mvc application where I demonstrate the best practices of doing this in mvc, you can see it in the download of the valueinjecter

 public ActionResult Edit(long id)
 {
      return View(modelBuilder.BuildModel(personService.Get(id)));
 }

 [HttpPost]
 public ActionResult Edit(PersonViewModel model)
 {
    if (!ModelState.IsValid)
       return View(modelBuilder.RebuildModel(model));    
       personService.Save(modelBuilder.BuildEntity(model));
       return RedirectToAction("Index");
 }

a quick demo of the ValueInjecter:

//build viewmodel
    personViewModel.InjectFrom(person)
                   .InjectFrom<CountryToLookup>(person);

//build entity
    person.InjectFrom(personViewModel)
          .InjectFrom<LookupToCountry>(personViewModel);
like image 181
Omu Avatar answered Oct 05 '22 12:10

Omu


There have been a few posts recently around the issue of validating your models, resulting in this post from Brad Wilson "Input Validation vs. Model Validation in ASP.NET MVC".

The initial issue was to do with how ASP.NET MVC handled validating a posted model, and if there were elements of your model that you didn't want edited and didn't supply fields for in the view, but your controllers were working with the whole model, it's possible that someone could craft a POST to your controller with the additional fields.

Therefore using a View specific Model enables you to ensure that only the fields you want edited can be edited.

like image 23
Zhaph - Ben Duguid Avatar answered Oct 05 '22 12:10

Zhaph - Ben Duguid