Automapper in ASP.NET Core 3.1 – Getting Started

by | Updated on May 30, 2020 | ASP.NET Core

In this article, we will talk about Automapper in ASP.Net Core Applications and how we can implement it with ease. We will go through the features of Automapper and the problems it solves by practical use cases. I will also leave the link to my GitHub Repository for the source code used in this guide.

The Problem

In order to maintain a separation of concern between various of your layers in a ASP.NET Core Project, it is advisable to have different models / Data transfer objects that are associated with a specific layer. This is a very good practice.

Let’s say we have 2 classes to be mapped, one is a domain object and other one is a view model object.

public class Developer
{  
   public string Name {get; set;}  
   public int Experience {get; set;}  
}  
public class DeveloperDTO
{  
   public string Name {get; set;}  
   public int Experience {get; set;}  
}  

Now, we need to link these objects to transfer the data between layers. So we start writing lines of code that says devDTO.Name = dev.Name and so on. This will be fine for one or a few classes. What if you have 100 classes in your application with multiple properties. At a point, this is will become a tedious task with repeated code. Do you get the point? It is also likely that you may even miss a property and end up with a null exception. This is quite a scenario that you would wish to avoid.

The Solution

What if there was a library that could handle this for you? Maps your objects to other objects automatically for you? All you would need to worry about is how to consume these objects and work with them. That is quite a lot of stress taken out for you in the longer run. This is where Automapper comes in.

What is Automapper?

Automapper is an object to object, convention-based mapping library that doesn’t need too much configuration. In simpler terms, it is a tool that transforms an object of Type T1 to an object of T2 (and back) with ease. It certainly makes a developer’s life easy.

Automapper in Asp.Net Core 3.1

Getting Started

For this tutorial, I will work on an ASP.NET Core 3.1 API to demonstrate the features of the Automapper. I use Visual Studio 2019 Community as my IDE (Best IDE for C# Development)

How to use Automapper in ASP.NET Core Application?

Installing the Automapper Package

You would just need to install this package which has a dependency with the main Automapper package. Thus both of them will get installed into your ASP.NET Core Application.

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

Configuring the Service

Now that we have installed the required packages, let’s configure it. Navigate to Startup.cs/Configuration method and add in the below line.

services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

Creating a Model and Data Transfer Object

We will create a very simple model and a DTO class.

 public class Developer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public decimal Experience { get; set; }
    }
 public class DeveloperDTO
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public decimal Experience { get; set; }
    }

Creating a Mapping Profile

Now that we our classes ready, we will need Mapping Profiles to let the application know about which object are linked to which.

What are Mapping Profiles?

Mapping profiles allow you to group mapping configurations together. A better way to organize your mapping is by using Mapping Profiles. For each entity / Area, you could create a Mapping Class that inherits from Profile.

When the application fires up, it initializes Automapper services that will look for classes that inherit from Profile base class and loads the specified mapping configurations.

Add a new class, Mappings/MappingProfile.cs

 public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<Developer, DeveloperDTO>(); //Map from Developer Object to DeveloperDTO Object
        }
    }

Developer Controller

To see how it works, let’s wire up a controller that takens in a Developer Model from the API endpoint and maps it to a DeveloperDTO Object. Let’s see how it’s done.

IMapper is an interface from Automapper that helps us use the library via dependency injection.

Create a new Controller, Controllers/DeveloperController.cs

 [Route("api/[controller]")]
    [ApiController]
    public class DeveloperController : ControllerBase
    {
        private readonly IMapper _mapper;
        public DeveloperController(IMapper mapper)
        {
            _mapper = mapper;
        }
        public async Task<IActionResult> Post(Developer developer)
        {
            var developerDtoMapped = _mapper.Map<DeveloperDTO>(developer);
            return Ok(developerDtoMapped);
        }
    }

Line #12 means that , using the IMapper interface, we map the incoming object of type Developer to type DeveloperDTO.Let’s open up Postman to test this endpoint by sending a Developer model in the request body.

am mapper

This is quite a simple mapping. Let’s do some more practical mappings. What is the properties to be mapped did not have same names?

Mapping Properties with Different Names

Automapper is a conventions based mapping, which means that the properties have to match so that the library can map them for you. But this is not the case always. In real-world applications, property names may vary. This is quite a good practical use case of Automapper in ASP.NET Core Applications. Let’s add a new property Salary and Compensation properties to each of our models.

In DeveloperDTO.cs

 public decimal Compensation { get; set; }

In Developer.cs

public decimal Salary { get; set; }

Now we need to explicitly tell Automapper that, ‘Every other property names match except one, so i need you to map Salary to Compensation’. Let’s see how we can do it. For this, open up your Mapping Profile and modify as below.

public MappingProfile()
        {
            CreateMap<Developer, DeveloperDTO>() //Map from Developer Object to DeveloperDTO Object
                .ForMember(dest => dest.Compensation,source => source.MapFrom(source => source.Salary)); //Specific Mapping
        }

At Line #4, we have mentioned that for the destination member Compensation ( from DeveloperDTO), we have to map from the source member Salary. Here is the result.

am differentname

Conditional Mapping

Let’s try to add some conditions in our mappings. I will add new boolean property, IsEmployed to our Developer DTO. This is my requirement. If the developer has a salary above 0, set the IsEmployed to true, else false. It;s quite easy to achieve this with Automapper.

In DeveloperDTO.cs

public bool IsEmployed { get; set; }

Modify the Mapping Profile as well.

public MappingProfile()
        {
            CreateMap<Developer, DeveloperDTO>() //Map from Developer Object to DeveloperDTO Object
                .ForMember(dest => dest.Compensation, source => source.MapFrom(source => source.Salary)) //Specific Mapping
                .ForMember(dest => dest.IsEmployed, source => source.MapFrom(source => source.Salary > 0 ? true : false));//Conditional Mapping
        }

Line #5 is similar to Line 4, except that we have introduced a condition factor to it. The code is quite self explanatory. Run the application and open up Postman. This is what you get. Conditional Validation is done.

am conditional

Reverse Mapping using Automapper

Now, in another use case scenario you want to convert the DeveloperDTO back to Developer model as well for specific requirement. Automapper supports bi-directional mapping as well. This is mostly best used in CQRS where you need to map objects in a reverse manner, especially while updating object.

To enable Bi-Directional mapping, use ReverseMap() function in your Mapping Profile.

public MappingProfile()
        {
            CreateMap<Developer, DeveloperDTO>() //Map Developer Object to DeveloperDTO Object
                .ForMember(dest => dest.Compensation, source => source.MapFrom(source => source.Salary)) //Specific Mapping                
                .ForMember(dest => dest.IsEmployed, source => source.MapFrom(source => source.Salary > 0 ? true : false))//Conditional Mapping
                .ReverseMap();
        }

Mapping Complex Objects

Till now we have only worked with strings and ints to map properties. When we have a Complex Object, like a nested class, we will have done a bit more configuration.

Let’s add a Address Class and DTO and insert it to the Developer Classes as well.

 public class Address
    {
        public string City { get; set; }
    }
public class AddressDTO
    {
        public string City { get; set; }
    }
public class Developer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public decimal Experience { get; set; }
        public decimal Salary { get; set; }
        public Address Address { get; set; }
    }
 public class DeveloperDTO
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public decimal Experience { get; set; }
        public decimal Compensation { get; set; }
        public bool IsEmployed { get; set; }
        public AddressDTO Address { get; set; }
    }

Yep, you guessed it right. You will just have to create a map for Address class to AddressDTO class. Quite simple. Your MappingProfile.cs would like this now.

 public MappingProfile()
        {
            CreateMap<Developer, DeveloperDTO>() //Map from Developer Object to DeveloperDTO Object
                .ForMember(dest => dest.Compensation, source => source.MapFrom(source => source.Salary)) //Specific Mapping                
                .ForMember(dest => dest.IsEmployed, source => source.MapFrom(source => source.Salary > 0 ? true : false))//Conditional Mapping
                .ReverseMap();
            CreateMap<Address, AddressDTO>();
        }
am nested 1

We are now able to perform mappings for Nested Classes with Automapper in ASP.NET Core applications.

Summary

We have learned how to use Automapper, the problem it solves, and how to implement automapper in ASP.NET Core Applications with ease. This is a sample demonstration/guide, whereas I am planning to build a boilerplate template for ASP.NET Core Web Applications that would help you get started with the best code practices and patterns for your new web application. I will keep you posted. Subscribe to be updated.

If you found this article helpful,

Buy me a coffeeBuy me a coffee

Source Code

The Completed Source code for ‘Automapper in Asp.Net Core’ is available in my Github.
Do Follow me on GitHub as well.

Frequently Asked Questions

3 Comments

  1. Yoel

    thanks for the tutorial download your code and run it and in adress I get null

    Reply
  2. Yoel

    I have a question if I have two tables connected to my user and role database
    and i want to list the information in the user table plus the information in the role table by performing these steps, the Get method gives me a null value

    Reply
  3. Yoel

    I could already solve this

    Reply

Submit a Comment

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

Follow codewithmukesh

Support Me!

Buy me a coffeeBuy me a coffee

Related Articles

Pin It on Pinterest