Implement Automapper in ASP.NET Core 3.1

In every application, there will be a need to map the object of one type to object of another type. Automapper is used to map these objects of dissimilar types without the need to write boring code to map each data member. Automapper in ASP.NET core comes handy when mapping objects between Model & DTO.

What is automapper & when to use it?

Automapper

Automapper is a popular small library for an object to object mapping used to map objects of different classes.

Let’s say you have two different classes EmployeeDTO & EmployeeModel with the same data members and you need to copy data from one object to another. Now you cannot set an instance of one object to another object as though data member match but objects are of different classes. You will have to use the traditional approach i.e. copy data from one object to another field by field.

To simply this job of mapping data from one object to objects Auto Mapper can be used. Auto Mapper is an open-source library and It maps the properties of two different objects.

Implement automapper in ASP.NET Core

Setup project for demonstration

Create new ASP.NET Core API Project

For implementation purpose, I have created a default ASP.NET Core 3.1 API Project using Visual Studio 2019

ASP.NET Core 3.1 API Project Creation

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.

NuGet Extension

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

Configure automapper in startup.cs

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

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 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.

Using employee mapping in Employee controller

Create an Employee controller as shown below. Automapper service will have to be injected into 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 & return 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 Employee controller post-action using postman we got the following result

mapper in ASP.NET Core

Newsletter Subscription

Stay updated! Instantly get notified about my new articles in your mailbox by subscribing via email

Mapping objects having different property names

To demonstrate how to map objects using automapper having different property names. We have modified 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 Employee Mapping Profile class in which we have added mapping for properties having different name i..e. EmployeeDTO=>Name to EmployeeModel=>FullName. Here 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 Employee controller post-action using postman we got the following result.

automapper conditional mapping

Mapping objects with conditional mapping

Here is the how to implement conditional mapping for 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));
    }
}

Mapping objects with Null Subsitution

This allows you to set an 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"));
}

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

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

  • No need to write boring code so saves time
EmployeeDTO.Name = EmployeeModel.Name
EmployeeDTO.Id = EmployeeModel.Id
  • Handles conditional mapping
  • Handles complex objects

Summary

Automapper 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.

Automapper on GitHub

You can also check my other article on Top 12 ASP.NET Core libraries for developers – https://procodeguide.com/programming/top-12-essential-asp-net-core-libraries

Complete source code for Automapper in ASP.NET Core is available on my GitHub for download

Automapper.Sample
https://github.com/procodeguide/Automapper.Sample
0 forks.
0 stars.
0 open issues.
Recent commits:

  1. What is Automapper?

    Automapper is a popular small library for an object to object mapping used to map objects of different classes.

  2. When to use Automapper?

    Use it to simply job like you have two different classes EmployeeDTO & EmployeeModel with the same data members and you need to copy data from one object to another

  3. What are advantages of Automapper?

    No need to write boring code so saves time, handles complex objects, conditional mapping, etc.

Hope you found this article useful
Buy me a coffeeBuy me a coffee

Leave a Reply

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