Back to: C#.NET Tutorials For Beginners and Professionals
AutoMapper ReverseMap in C# with Examples
In this article, I am going to discuss the AutoMapper ReverseMap in C# with some examples. Please read our previous article before proceeding to this article where we discussed how to map Complex type to Primitive Type using AutoMapper in C# with examples. This is one of the most important concepts to understand in AutoMapper and at the end of this article, you will understand how automapper reverse mapping in c# works.
What is AutoMapper Reverse Mapping in C#?
The Automapper Reverse Mapping is nothing but the two-way mapping which is also called as bidirectional mapping.
As of now, the mapping we discussed are one directional means if we have two types let’s say Type A and Type B, then we Map Type A with Type B. But using Automapper Reverse mapping it is also possible to Map Type B with Type A.
Let us understand C# AutoMapper Reverse Mapping with an example.
We are going to use the following three classes for this demo.
To implement the Reverse Mapping using Automapper in C# we need to use the ReverseMap option as shown in the below image.
Below is the complete example.
The code self explained. So, please go through the comment lines.
using System; using AutoMapper; namespace AutoMapperDemo { class Program { static void Main(string[] args) { //Step1: Initialize the Mapper var mapper = InitializeAutomapper(); //Step2: Create the Order Request var OrderRequest = CreateOrderRequest(); //Step3: Map the OrderRequest object to Order DTO var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest); //Step4: Print the OrderDTO Data Console.WriteLine("After Mapping - OrderDTO Data"); Console.WriteLine("OrderId : " + orderDTOData.OrderId); Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems); Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount); Console.WriteLine("CustomerId : " + orderDTOData.CustomerId); Console.WriteLine("Name : " + orderDTOData.Name); Console.WriteLine("Postcode : " + orderDTOData.Postcode); Console.WriteLine("MobileNo : " + orderDTOData.MobileNo); Console.WriteLine(); //Step5: modify the OrderDTO data orderDTOData.OrderId = 10; orderDTOData.NumberOfItems = 20; orderDTOData.TotalAmount = 2000; orderDTOData.CustomerId = 5; orderDTOData.Name = "Smith"; orderDTOData.Postcode = "12345"; //Step6: Reverse Map mapper.Map(orderDTOData, OrderRequest); //Step7: Print the Order Data Console.WriteLine("After Reverse Mapping - Order Data"); Console.WriteLine("OrderNo : " + OrderRequest.OrderNo); Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems); Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount); Console.WriteLine("CustomerId : " + OrderRequest.Customer.CustomerID); Console.WriteLine("FullName : " + OrderRequest.Customer.FullName); Console.WriteLine("Postcode : " + OrderRequest.Customer.Postcode); Console.WriteLine("ContactNo : " + OrderRequest.Customer.ContactNo); Console.ReadLine(); } private static Order CreateOrderRequest() { return new Order { OrderNo = 101, NumberOfItems = 3, TotalAmount = 1000, Customer = new Customer() { CustomerID = 777, FullName = "James Smith", Postcode = "755019", ContactNo = "1234567890" }, }; } static Mapper InitializeAutomapper() { var config = new MapperConfiguration(cfg => { cfg.CreateMap<Order, OrderDTO>() //OrderId is different so map them using For Member .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo)) //Customer is a Complex type, so Map Customer to Simple type using For Member .ForMember(dest => dest.Name, act => act.MapFrom(src => src.Customer.FullName)) .ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.Customer.Postcode)) .ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.Customer.ContactNo)) .ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.Customer.CustomerID)) .ReverseMap(); }); var mapper = new Mapper(config); return mapper; } } public class Order { public int OrderNo { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public Customer Customer { get; set; } } public class Customer { public int CustomerID { get; set; } public string FullName { get; set; } public string Postcode { get; set; } public string ContactNo { get; set; } } public class OrderDTO { public int OrderId { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public int CustomerId { get; set; } public string Name { get; set; } public string Postcode { get; set; } public string MobileNo { get; set; } } }
When you run the application, it displays the data as expected as shown in the below image.
Modifying Models:
Let us modify the models as shown below. As you can see in the below image, now the complex type property is present in the OrderDTO class and primitive types are present in the Order class.Â
Let’s implement the AutoMapper ReverseMap() function and see whether we get the results as expected or not. Modify the Mapper initialization to implement mapping and reverse mapping for the above types as shown in the below image.
Below is the code for the complete example
using System; using AutoMapper; namespace AutoMapperDemo { class Program { static void Main(string[] args) { //Step1: Initialize the Mapper var mapper = InitializeAutomapper(); //Step2: Create the Order Request var OrderRequest = CreateOrderRequest(); //Step3: Map the OrderRequest object to Order DTO var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest); //Step4: Print the OrderDTO Data Console.WriteLine("After Mapping - OrderDTO Data"); Console.WriteLine("OrderId : " + orderDTOData.OrderId); Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems); Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount); Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID); Console.WriteLine("FullName : " + orderDTOData.customer.FullName); Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode); Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo); Console.WriteLine(); //Step5: modify the OrderDTO data orderDTOData.OrderId = 10; orderDTOData.NumberOfItems = 20; orderDTOData.TotalAmount = 2000; orderDTOData.customer.CustomerID = 5; orderDTOData.customer.FullName = "James Smith"; orderDTOData.customer.Postcode = "12345"; //Step6: Reverse Map mapper.Map(orderDTOData, OrderRequest); //Step7: Print the Order Data Console.WriteLine("After Reverse Mapping - Order Data"); Console.WriteLine("OrderNo : " + OrderRequest.OrderNo); Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems); Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount); Console.WriteLine("CustomerId : " + OrderRequest.CustomerId); Console.WriteLine("Name : " + OrderRequest.Name); Console.WriteLine("Postcode : " + OrderRequest.Postcode); Console.WriteLine("MobileNo : " + OrderRequest.MobileNo); Console.ReadLine(); } private static Order CreateOrderRequest() { return new Order { OrderNo = 101, NumberOfItems = 3, TotalAmount = 1000, CustomerId = 777, Name = "James Smith", Postcode = "755019", MobileNo = "1234567890" }; } static Mapper InitializeAutomapper() { var config = new MapperConfiguration(cfg => { cfg.CreateMap<Order, OrderDTO>() .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo)) .ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer() { CustomerID = src.CustomerId, FullName = src.Name, Postcode = src.Postcode, ContactNo = src.MobileNo })) .ReverseMap(); }); var mapper = new Mapper(config); return mapper; } } public class Order { public int OrderNo { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public int CustomerId { get; set; } public string Name { get; set; } public string Postcode { get; set; } public string MobileNo { get; set; } } public class Customer { public int CustomerID { get; set; } public string FullName { get; set; } public string Postcode { get; set; } public string ContactNo { get; set; } } public class OrderDTO { public int OrderId { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public Customer customer { get; set; } } }
Now run the application and see the output.
As you can see from the above output, the automapper reverse mapping work as expected for the primitive types but not working for the complex type.
So when both classes have members that are named equally then the AutoMapper ReverseMap() function works as expected. But if the classes contain members that are different and not mapped via the default (per naming) mapping then this does not work as expected.
How to make the two mapping works as expected?
If you want to make the two-way mapping work as expected then you need to do the Mapping via ForMember. So modify the Mapper initialization to tell the mapping for the complex type as shown in the below image.
Below is the complete code.
using System; using AutoMapper; namespace AutoMapperDemo { class Program { static void Main(string[] args) { //Step1: Initialize the Mapper var mapper = InitializeAutomapper(); //Step2: Create the Order Request var OrderRequest = CreateOrderRequest(); //Step3: Map the OrderRequest object to Order DTO var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest); //Step4: Print the OrderDTO Data Console.WriteLine("After Mapping - OrderDTO Data"); Console.WriteLine("OrderId : " + orderDTOData.OrderId); Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems); Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount); Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID); Console.WriteLine("FullName : " + orderDTOData.customer.FullName); Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode); Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo); Console.WriteLine(); //Step5: modify the OrderDTO data orderDTOData.OrderId = 10; orderDTOData.NumberOfItems = 20; orderDTOData.TotalAmount = 2000; orderDTOData.customer.CustomerID = 5; orderDTOData.customer.FullName = "James Smith"; orderDTOData.customer.Postcode = "12345"; //Step6: Reverse Map mapper.Map(orderDTOData, OrderRequest); //Step7: Print the Order Data Console.WriteLine("After Reverse Mapping - Order Data"); Console.WriteLine("OrderNo : " + OrderRequest.OrderNo); Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems); Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount); Console.WriteLine("CustomerId : " + OrderRequest.CustomerId); Console.WriteLine("Name : " + OrderRequest.Name); Console.WriteLine("Postcode : " + OrderRequest.Postcode); Console.WriteLine("MobileNo : " + OrderRequest.MobileNo); Console.ReadLine(); } private static Order CreateOrderRequest() { return new Order { OrderNo = 101, NumberOfItems = 3, TotalAmount = 1000, CustomerId = 777, Name = "James Smith", Postcode = "755019", MobileNo = "1234567890" }; } static Mapper InitializeAutomapper() { var config = new MapperConfiguration(cfg => { cfg.CreateMap<Order, OrderDTO>() .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo)) .ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer() { CustomerID = src.CustomerId, FullName = src.Name, Postcode = src.Postcode, ContactNo = src.MobileNo })) .ReverseMap() .ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.customer.CustomerID)) .ForMember(dest => dest.Name, act => act.MapFrom(src => src.customer.FullName)) .ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.customer.ContactNo)) .ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.customer.Postcode)); }); var mapper = new Mapper(config); return mapper; } } public class Order { public int OrderNo { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public int CustomerId { get; set; } public string Name { get; set; } public string Postcode { get; set; } public string MobileNo { get; set; } } public class Customer { public int CustomerID { get; set; } public string FullName { get; set; } public string Postcode { get; set; } public string ContactNo { get; set; } } public class OrderDTO { public int OrderId { get; set; } public int NumberOfItems { get; set; } public int TotalAmount { get; set; } public Customer customer { get; set; } } }
Now run the application and you will see the output as expected as shown in the below image.
In the next article, I am going to discuss Conditional Mapping using AutoMapper in C# with examples. Here, in this article, I try to explain AutoMapper Reverse Mapping in C# with examples. I hope this C# AutoMapper Reversemap article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.
nice article…thank you.