Suppose I have a class Person
.
Model: Person.cs
:
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Department Department { get; set; }
}
Then I have a view model that contains two conversion methods:
- A
ToPerson()
to map toPerson
- A static
FromPerson()
that constructs aPersonViewModel
fromPerson
.
View Model: PersonViewModel.cs
class PersonViewModel
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Email, Required]
public string Email { get; set; }
public int DepartmentId { get; set; }
public Person ToPerson(Department department) => new()
{
Id = this.Id, Name = this.Name, Email = this.address, Department = department
};
public static PersonViewModel FromPerson(Person p) => new()
{
Id = p.Id, Name = p.Name, Email = p.Email, DepartmentId = p.Department.Id
};
}
This enables me to write code like this in the controller:
Controller: PersonsController.cs
public class PersonsController : Controller
{
public IActionResult Create(PersonViewModel pvm)
{
if (ModelState.IsValid)
{
Department dept = departmentService.Get(pvm.DepartmentId);
Person person = pvm.ToPerson(dept);
personService.Add(person);
return View(nameof(Index));
}
return View(pvm);
}
[HttpGet]
public IActionResult Edit(int? id)
=> personService.Get(id) is not null and var person
? View(PersonViewModel.FromPerson(person))
: NotFound();
}
I have come across AutoMapper. However, I feel having methods like this gives me more flexibility over the mapping operation like handling custom cases where a one-to-one mapping is not relevant while also tidying up controller boilerplate. (See this answer where it is mentioned how AutoMapper may not always be well-suited for every use case.)
I know the question "Should I do this?" will be opinion-based. My question is:
"Are there any side-effects or cons of doing it this way? Does it violate any design principles or is there anything against having logic in a view model? And are there better ways to tidy up mapping operations in controller actions?"