0

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?

4
  • Do you assert that your AutoMapper configuration is correct at the end of the bootstrapper? (i.e. Mapper.AssertConfigurationIsValid();) Commented Aug 17, 2014 at 15:30
  • I think you pass incorrect parameter, the comment is set domain from viewModel, but it seems you actually set from domain to viewModel. First parameter is source and second parameter is destination, try to switch the parameter.. Commented Aug 17, 2014 at 15:55
  • @EdChapel - doing that I got an error - saying unmapped members were found - including the CreateDate/CreateUserName, UpdateDate, UpdateUserName which are conatined in the AuditableEntity class which Employee inherits from - how can I set AutoMapper to ignore these propertys which are not in my viewModel I want to map too? Commented Aug 17, 2014 at 16:00
  • @Ctrl_Alt_Defeat Search for 'AutoMapper Ignore'. Mapper.Map(employee, viewModel.Employee).ForMember(e => e.CreateDate, x => x.Ignore()); Commented Aug 17, 2014 at 18:24

2 Answers 2

2

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 
Sign up to request clarification or add additional context in comments.

Comments

0

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); 

5 Comments

new instance, then how do we get the result ?
The Map() function take an instance of the source type and an instance of the target type. The CreateMap() is where you register the types.. try it... you'll see.
The Mapping is done based on the types you've registered but you must pass instances to the Map() method. I typically create a static MapFrom() method to my Mapper classes.
perhaps what you meant is model.Employee employee = Mapper.Map(viewEmployee, new model.Employee()); or viewmodel.EmployeeDetailsViewModel model = new EmployeeDetailsViewModel(); model.Employee = Mapper.Map(employee, new viewmodel.Employee());
I've updated my answer to what AutoMapper is suppose to be coded to get an instance of a populated model object.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.