Easy Way to Setup AutoMapper in ASP.NET Core

AutoMapper is an object-object mapper library

In Realtime application we assign values from one object to another object in many places such as mapping View Model to Model in controller similar way we do mapping again for showing values on Views by getting an object from the database back assigning to ViewModel.

In future, if we add a new property again to class, then the same assignment needs to do at all place where are doing object to object mapping right.

To overcome this object to object mapping, again and again, we can use AutoMapper.

Let’s start with creating an application.

Steps by Steps to Setup AutoMapper in ASP.NET Core

1. Create ASP.NET Core Web Application

Install automapper NuGet package

Install package AutoMapper.Extensions.Microsft.DependencyInjection & this package depends on the AutoMapper package which will also get installed with this package.

Create sample EmployeeDTO & EmployeeModel classes

public class EmployeeDTO
{
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public double Salary { get; set; }
}

public class EmployeeModel 
{
    public long Id { get; set; } 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public double Salary { get; set; } 
}

2. Configure automapper in startup.cs

public void ConfigureServices(IServiceCollection services) 
{
    services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); 
}
//Remaining code has been removed

3. Create an automapper mapping profile as EmployeeProfile.cs

Creating Mapping profiles is a better way to organize your object mappings. This profile tells automapper about which object links to which another object, which property of one object links to which property of other object and even let’s configure conditional mappings.

Create a mapping profile class that inherits from AutoMapper.Profile and add the configuration in the constructor of that mapping profile class

public class EmployeeProfile : Profile 
{
    public EmployeeProfile() 
    {
        CreateMap<EmployeeDTO, EmployeeModel>(); 
    }
}

Do note that with the above CreateMap you can map from EmployeeDTO to EmployeeModel but reverse mapping will not be supported. Reverse Maps will have to be used for bidirectional mapping.

4. Using employee mapping in Employee controller

Create an Employee controller as shown below. Automapper service will have to be injected into the controller using constructor dependency injection (Refer here for more details on Dependency Injection). Here Employee controller’s post method takes an object of type EmployeeDTO and using automapper maps it to EmployeeModel & returns the same as JSON.

[Route("api/[controller]")] 
[ApiController] 
public class EmployeeController : ControllerBase 
{
    private readonly IMapper _mapper; 

    public EmployeeController(IMapper mapper) 
    {
        _mapper = mapper; 
    }

    // POST api/<EmployeeController> 
    [HttpPost] 
    public IActionResult Post([FromBody] EmployeeDTO _employeeDTO) 
    {
        var employeeModel = _mapper.Map<EmployeeModel>(_employeeDTO); 
        return Ok(employeeModel); 
    }
}

After executing the above project and calling the Employee controller post-action using postman we got the following result

5. Mapping objects having different property names

To demonstrate how to map objects using automapper having different property names. We have modified the class EmployeeModel property name for Name to FullName.

public class EmployeeDTO 
{
    public long Id { get; set; } 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public double Salary { get; set; } 
}
public class EmployeeModel 
{
    public long Id { get; set; } 
    public string FullName { get; set; } 
    public int Age { get; set; } 
    public double Salary { get; set; } 
}
Below is the code for the Employee Mapping Profile class in which we have added a mapping for properties having different names i..e. EmployeeDTO=>Name to EmployeeModel=>FullName. ere we have used method ForMember to specify the mapping
public class EmployeeProfile : Profile 
{
    public EmployeeProfile() 
    {
        CreateMap<EmployeeDTO, EmployeeModel>() 
             .ForMember(empmodel => empmodel.FullName, empdto => empdto.MapFrom(empdto => empdto.Name)); 
    }
}

After executing the above project and calling the Employee controller post-action using postman we got the following result.

6. Mapping objects with conditional mapping

Here is the how-to implement conditional mapping for objects in the Employee Mapping Profile class

public class EmployeeProfile : Profile 
{
    public EmployeeProfile() 
    {
        CreateMap<EmployeeDTO, EmployeeModel>() 
             .ForMember(empmodel => empmodel.FullName, empdto => empdto.MapFrom(empdto => empdto.Name)) 
             .ForMember(empmodel => empmodel.Salary, empdto => empdto.MapFrom(empdto => empdto.Age > 55 ? empdto.Salary * 10 : empdto.Salary)); 
    }
}

7. Mapping objects with Null Subsitution

This allows you to set a default or alternate value for the destination data member in case the source data member is null

public EmployeeProfile()
{
    CreateMap<EmployeeDTO, EmployeeModel>()
        .ForMember(empmodel => empmodel.Telephone, empdto => empdto.NullSubstitute("Not Available"));
}

8. Mapping objects with Reverse Map

Do note that with CreateMap you can map from source (EmployeeDTO) to destination (EmployeeModel) but reverse mapping will not be supported. Reverse Maps will have to be used for bidirectional mapping.

public class EmployeeProfile : Profile
{
    public EmployeeProfile()
    {
        CreateMap<EmployeeDTO, EmployeeModel>()
            .ForMember(empmodel => empmodel.FullName, empdto => empdto.MapFrom(empdto => empdto.Name))
            .ForMember(empmodel => empmodel.Salary, empdto => empdto.MapFrom(empdto => empdto.Age > 55 ? empdto.Salary * 10 : empdto.Salary))
            .ReverseMap();
    }
}

9. Mapping Objects of Complex Types

EmployeeDTO & EmployeeModel classes have been modified to add a new property which is of a type of custom class as shown below

public class TelephoneNumberDTO
{
    //1 - Home, 2 - Office, 3 - Mobile
    public int PhoneType { get; set; }
    public string PhoneNumber { get; set; }
}
public class TelephoneNumberModel
{
    //1 - Home, 2 - Office, 3 - Mobile
    public int PhoneType { get; set; }
    public string PhoneNumber { get; set; }
}
public class EmployeeDTO
{
    public long Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public double Salary { get; set; }
    public TelephoneNumberDTO Telephone { get; set; }
}
public class EmployeeModel
{
    public long Id { get; set; }
    public string FullName { get; set; }
    public int Age { get; set; }
    public double Salary { get; set; }
    public TelephoneNumberModel Telephone { get; set; }
}

Here is the how to map complex objects in Employee Mapping Profile class

public class EmployeeProfile : Profile
{
    public EmployeeProfile()
    {
        CreateMap<EmployeeDTO, EmployeeModel>()
            .ForMember(empmodel => empmodel.FullName, empdto => empdto.MapFrom(empdto => empdto.Name))
            .ForMember(empmodel => empmodel.Salary, empdto => empdto.MapFrom(empdto => empdto.Age > 55 ? empdto.Salary * 10 : empdto.Salary))
            .ReverseMap();
        CreateMap<TelephoneNumberDTO, TelephoneNumberModel>()
            .ReverseMap();
    }
}

Advantages of automapper in ASP.NET Core

  • No need to write boring code so saves time
  • Handles conditional mapping
  • Handles complex objects

Summary

Automapper in ASP.NET Core is used to map objects of dissimilar types without the need to write boring code to map each data member.

We used automapper in ASP.NET Core to map objects of dissimilar types. It was easy to map objects having the same property names with minimal coding. Though different property names required some mapping to map properties within classes.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *