Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net mvc viewmodels. How much logic (if any) should they contain

I've been looking into view models for mvc and I'm looking for the best way to do them. I've read loads of different articles but none seem to be clear as the "best way." So far example I might have a Customer model with the following properties:

  • First Name
  • Last Name
  • Title
  • Location

Where location is a foreign key to a location table in the database.

I want to be able to edit this customer but only the first name, last name and location. I'm not bothered about the title in the edit. So in my view I will need to pass a customer and a selected list.

Now from what I've read I have the following options (there's probably many more).

So my question is basically which is the best one?

1)

Add a select list to the ViewData["Location"] and just create a strongly typed view of customer?

2)

Create a view model where I pass a customer and select list (the data access is done in the controller):

public class ViewModelTest
{
    public Customer Customer { get; set; }
    public SelectList Locations { get; set; }

    public ViewModelTest(Customer customer, SelectList locations)
    {
        Customer = customer;
        Locations = locations;
    }
}

3)

Create a view model where I pass a customer and list of locations and create the select list in the view model.

public class ViewModelTest
{
    public Customer Customer { get; set; }
    public SelectList Locations { get; set; }

    public ViewModelTest(Customer customer, List<Location> locations, string selectedLocation)
    {
        Customer = customer;
        Locations = new SelectList(locations, "LocationID", "LocationName", selectedLocation);
    }
}

4)

Pass a customer and repository and do the data access in the view model.

public class ViewModelTest
{
    public Customer Customer { get; set; }
    public SelectList Locations { get; set; }

    public ViewModelTest(Customer customer, IRepository repository, string selectedLocation)
    {
        Customer = customer;
        Locations = new SelectList(repository.GetLocations(), "LocationID", "LocationName", selectedLocation);
    }
}

5)

Create the view model with just the properties I need:

public class ViewModelTest
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public SelectList Locations { get; set; }

    public ViewModelTest(Customer customer, SelectList locations)
    {
        FirstName = customer.FirstName;
        LastName = customer.LastName ;
        Locations = locations;
    }
}

6)

Or some other combination of the above or another way.

All opinions welcome.

like image 967
lancscoder Avatar asked Jun 17 '10 10:06

lancscoder


People also ask

What is the purpose of ViewModel in MVC?

In ASP.NET MVC, ViewModel is a class that contains the fields which are represented in the strongly-typed view. It is used to pass data from controller to strongly-typed view.

How many views does the model can have in MVC?

ASP.NET MVC view can't have more than one model so if we need to display properties from more than one model in the view, it is not possible.

Can ViewModels have methods?

Defines a class used to provide values and methods to the component's view.


1 Answers

Here's what I may suggest: have a view model which reflects the fields of strongly typed view:

public class SomeViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Location { get; set; }
    public IEnumerable<SelectListItem> PossibleLocations { get; set; }
}

And in your controller action populate this view model:

public ActionResult Index()
{
    var customer = Repository.GetCustomer();
    var locations = Repository.GetLocations();
    var viewModel = new SomeViewModel
    {
        FirstName = customer.FirstName,
        LastName = customer.LastName,
        Location = customer.Location,
        PossibleLocations = new SelectList(locations, "LocationID", "LocationName", customer.Location);
    };
    return View(viewModel);
}

[HttpPost]
public ActionResult Index(SomeViewModel viewModel)
{
    // TODO: Handle the form submission
    return View(viewModel);
}

Of course doing the mapping between the model and the view model manually as shown my example could become quite cumbersome and in this case I would recommend you looking at AutoMapper.

like image 182
Darin Dimitrov Avatar answered Sep 18 '22 13:09

Darin Dimitrov