by thorhalvor

Custom mapping? No, I use Automapper!

In the previous posts i wrote about web applications communicating with the backend through a JSON REST API. I mentioned that I like to design specific REST methods for the given Views. That means we have to do some mapping from the objects given by the backend to the viewmodel objects. Writing a custom mapping class is not rocket science but it is really boring to maintain when properties are removed or introduced during its lifetime.

Using Automapper from Jimmy Bogard can in some best-cases reduce the code needed to only two lines of code. No matter how many properties exist in the object.

Automapper has moved to github and you can read more about it there, and it is also available as an nuget pacakge.

I will not go in-depth, but let me give you some examples:

I have a Customer object with Firstname and Lastname. I also have an CustomerViewModel object with the same properties. To verify i have wrote the test below. Linenumber 5 and 6 are the only lines of code needed to perform the map.


 1: [Test]
 2: public void WhenMappingCustomerToViewModel_ThenAllPropertiesShouldBeMapped()
 3: {
 4:     var customer = new Customer{Firstname = "John",Lastname = "Johnsen"};;
 5:     Mapper.CreateMap<Customer, CustomerViewModel>();
 7:     var customerViewModel = Mapper.Map<Customer>(customer);
 9:     Assert.AreEqual(customer.Firstname,customerViewModel.Firstname);
 10:     Assert.AreEqual(customer.Lastname,customerViewModel.Lastname);
 11: }


I will give you some more advanced examples later on in this posts, I will just start telling you about Automappers method “AssertConfigurationIsValid”. A very simple test that you always should add in your tests suite:

 1: [Test]
 2: public void WhenMappingCustomerToViewModel_ConfigurationShouldBeValid()
 3: {
 4:     Mapper.CreateMap<Customer, CustomerViewModel>();
 5:     Mapper.AssertConfigurationIsValid();
 6: }

AssertConfiguraitonIsValid will raise an exception if some of the properties in CustomerViewModel is NOT mapped from the Customer object. If for example only the CustomerViewModel has an Age property the given exception will be raised:

AutoMapper.AutoMapperConfigurationException : The following 1 properties on ns+CustomerViewModel are not mapped:
Add a custom mapping expression, ignore, or rename the property on ns+Customer.

Lower- UpperCase does not matter

In Javscript and Json it is a standard to have lowercase properties. So if my CustomerViewModel had properties firstname and lastname and Customer has FirstName and LastName everything will just work. I do not have to change the mappingclass.


If the Customer has an object of type Address, and Address has the property Line1, then this value will be automatically mapped if the CustomerViewModel has an property called AddressLine1. Eks Customer.Address.Line1 will be automatically mapped to CustomerViewModel.AddressLine1.


The Customer might have a property DateOfBirth of type DateTime, but in CustomerViewModel I have a property called Birthdate of type string. And I want this string to be in the format ddMMyyyy. In these cases i have to add a line when calling Mapper.CreateMap()

Mapper.CreateMap<Customer, CustomerViewModel>()
    .ForMember(d => d.BirthDate, o => o.MapFrom(s => s.DateOfBirth.ToString("ddMMyyyy")));


Mapping a IEnumerable<T> (added later because of specific request in email)

The framework support mapping of IEnumerable<T> as long as you have created a map for T.

 1: [Test]
 2: public void WhenMappingAListOfCustomersToViewModel_ThenAListWithAllTheViewModelsShouldBeMapped()
 3: {
 4:     var customer = new Customer{Firstname = "John",Lastname = "Johnsen"};
 5:     var customer2 = new Customer{Firstname = "hans",Lastname = "hansen"};
 6:     var customList = new List<Customer> { customer, customer2 };
 8:     Mapper.CreateMap<Customer, CustomerViewModel>()
 9:         .ForMember(d => d.BirthDate, o => o.MapFrom(s => s.DateOfBirth.ToString("ddMMyyyy")));
 11:     var customerViewModelList = Mapper.Map<IEnumerable<Customer>>(customList);
 13:     Assert.AreEqual(customList.Count(), customerViewModelList.Count());
 14: }


So to summarize, Automapper is really powerful and can save you many hours of boring mapping implementation.

  • Njål Gjermundshaug

    This is going to save me a lot of time. I can probably retire by the age of 48 now. Thanks a lot!!

  • Stian

    Wow! I had now idea this could be done so easy, just saved me heaps for boring mapping on my MVC project! Thanks Thor Halvor!