11

Currently I use private static methods in my controller file to map domain model to view model and vice-versa. Like below:

public ActionResult Details(int personID)
{
    Person personDM = service.Get(personID);
    PersonViewModel personVM = MapDmToVm(personDM);
    return View(personVM);
}

private static PersonViewModel MapDmToVm(Person dm)
{
   PersonViewModel vm;
   // Map to VM
   return vm;
}

Is there any other standard way to do this?

Saravana
  • 37,852
  • 18
  • 100
  • 108
  • 1
    You might find my answer [here](http://stackoverflow.com/questions/14131804/view-models-and-dependency-injection/14132184#14132184) useful. – Tim M. Jun 10 '14 at 07:27

2 Answers2

21

I prefer to put the mapping logic inside the view model (dto) class, because we want to keep the domain model as clean as possible and also the domain model might change overtime.

public class Person
{
    public string Name {get; set;}
}

public class PersonViewModel
{
    public string Text {get; set;}

    public static implicit operator PersonViewModel(Person dm)
    {
        var vm = new PersonViewModel { Text = dm.Name };
        return vm;
    }

    public static implicit operator Person(PersonViewModel vm)
    {
        var dm = new Person { Name = vm.Text };
        return dm;
    }
}

and use it in the controller without explicit casting.

Person dm = service.Get(id);
PersonViewModel vm = dm;
Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67
  • I personally prefer this way, too, arguing that the ViewModel already "knows" how to represent the model in a way that fits for the view, so the "knowledge" of how to map between the two representations belongs there too. – chiccodoro Jun 10 '14 at 07:30
  • @chiccodoro agree, usually the view model(dto) are in the UI project, and domain model in the server project, and UI project adds reference to server project. – Yuliam Chandra Jun 10 '14 at 07:36
  • 8
    Only thing, I would personally stay off implicit operators as they can add some confusion about whether a certain piece of code operates on the domain model or the view model. I have defined two methods `FromModel`, `ToModel` instead. – chiccodoro Jun 10 '14 at 08:00
  • 6
    How would you build a ViewModel that was composed of multiple domain models? – Mister Epic Jun 20 '14 at 12:57
  • 1
    When I have a SomeViewModel that is a combination of two other models, I am unable to use your method. I get the error, "Overloadable unary operator expected". Essentially, I am trying to use `public static implicit operator SomeViewModel(Model1 model1, Model2 model2)` – René Kåbis Jul 21 '16 at 23:25
4

Since the mapping is not always trivial, I think that it might be better to separate it into a different class other than the viewmodel.

That way each class has its own single responsibility. You might want to add an extension method to your domain model, something like:

public static MyViewModel ToViewModel(this MyDomainModel model)
    {
      // mapping code goes here
    }

You also might consider using automapper and call its Map method from your controller.

BornToCode
  • 9,495
  • 9
  • 66
  • 83