Ctrl_Alt_Defeat
Ctrl_Alt_Defeat

Reputation: 4009

AutoMapper not working as expected?

I have a class at my Domain layer something as below:

 public class Employee : AuditableEntity
    {
        public string FirstName { get; set; }
        public string Surname { get; set; }
        public double Salary{ get; set; }
        public int PhoneNo { get; set; }

        public double Bonus
        {
            get { return Salary + EmployeeAdditionals.Sum(e => e.Value); }
        }

        // virtual allow lazy loading
        public virtual ReadOnlyCollection<EmployeeAdditional> EmployeeAdditionals { get; private set; }

        // Paramterless constructor for EF
        public Employee()
        {
            EmployeeAdditionals = new List<EmployeeAdditional>();
        }

        public void AddAdditionalInfo(EmployeeAdditional additionalInfo)
        {
            additionalInfo.Employee = this;
            additionalInfo.EmployeeId = Id;

            ((Collection<EmployeeAdditional>) EmployeeAdditionals).Add(additionalInfo);
        }

I then have the following viewModel class in my MVC 5 Application:

 public class EmployeeDetailsViewModel : BaseViewModel
    {
        public EmployeeDetailsViewModel()
        {
            Employee = new Employee();
        }

        public Employee Employee { get; set; }
        //Other fields

    }

    public class Employee
    {
        [DisplayName("Employee First Name")]
        public string FirstName { get; set; }

        [DisplayName("Employee Surname")]
        public string Surname{ get; set; }

        public double Salary{ get; set; }

        [RegEx for Phone Number and Error Mesage]
        public int PhoneNo{ get; set; }

        public double Bonus { get; set; }
    }

I have mapping then in my controllers and viewModel builder to map my viewmodel to my domain model and domain model back to view model and I am attempting to use AutoMapper for this.

Using manual mapping something like below:

// set domain from viewModel
employee.FirstName= model.Employee.FirstName;
//etc for rest of fields

// set view model from domain
viewModel.Employee.FirstName = employee.FirstName;
//etc for rest of fields

Now in my AutoMapperBootstrapper class in Setup method I have the following:

  Mapper.CreateMap<Domain.Models.Employee, Employee>();
  Mapper.CreateMap<Employee, Domain.Models.Employee>();

Then I am using this is following in my controller and viewmodel builder:

//set domain from viewModel
Mapper.Map(employee, model.Employee);

// set viewmodel from domain
Mapper.Map(viewModel.Employee, employee);

When I hit a breakpoint on mapping from domain to viewModel I see the model.Employee with the values from screen but when I step over this line the values do not get mapped to domain employee and then the model.Emplyee values are reset to null for the strings, 0.0 for double, etc.

Is there something incorrect with my configuration or use of automapper?

Upvotes: 0

Views: 2622

Answers (2)

Yuliam Chandra
Yuliam Chandra

Reputation: 14640

You pass wrong parameter. If you want to use existing instance, make sure first parameter is source and second parameter is destination.

Try to switch the parameter.

//set domain from viewModel (viewModel is the source)
Mapper.Map(model.Employee, employee);
              ^^^^^         ^^^^^
              source      destination 

// set viewmodel from domain (domain is the source)
Mapper.Map(employee, viewModel.Employee);
            ^^^^^           ^^^^^
            source      destination 

Upvotes: 2

T McKeown
T McKeown

Reputation: 12847

Shouldn't your map code actually be like this? You have to use instances for Map(), it looks like you are using Types

//set domain from viewModel
Mapper.Map(viewEmployee, new model.Employee());

// set viewmodel from domain
Mapper.Map( employee, new viewmodel.Employee());

This is how I would expect you to use it:

var viewModel = Mapper.Map<ViewModel.Employee>(domainModel);  <-- this creates a ViewModel for a Domain Model

and the reverse would be:

var domainModel  = Mapper.Map<Domain.Employee>(viewModel);

Upvotes: 0

Related Questions