Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automapper Using .NET Core API 2.1

0.00/5 (No votes)
12 Aug 2018 1  
This article helps with getting started with automapper and use some of the commonly used functionalities.

Introduction

AutoMapper is an object – to – object mapping which is used to map dissimilar objects with less hassle. One of the most common scenarios for Automapper is when trying to convert an actual object to a DTO object.

To give you a better example, consider the following code:

var Department = GetDepartmentDetails();

DepartmentDetailsDTO obj = new DepartmentDetailsDTO()
{
   obj.Name = Department.Name,
   obj.Id = Department.Id,
   ...
   ...
   //So on . . 
}

Imagine the number of lines of code wasted just to ignore a few properties of the main object. So here is where AutoMapper comes in handy by replacing the above block of code into a single line!

In this article, we are going to look at how to set up Automapper in your project and use some of its most popular features. I will be showing on a .NET ASP Core 2.1 API project.

Background

An idea of APIs and dependency injection is required since we are going to inject the mapper object into our controller. Some basic understanding of LINQ is preferred.

Initial Setup

First, let's create a new .NET ASP core:

Auto_Mapper

Next up, let's add the NuGet Package for Automapper. Here, we are going to the dependency injection package called AutoMapper.Extensions.Microsoft.DependencyInjection as shown in the image below:

Auto_Mapper1

Now that AutoMapper is installed, we have to configure the startup.cs class to let it know that we are going to inject automapper.

This is a simple one line of code which is shown below inside the ConfigureServices method:

//Startup.cs
public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
   services.AddAutoMapper(); // Adding automapper
}

Mapping Profiles

We must add mapping profiles to our projects to tell Automapper the correct way of mapping objects.

A mapping profile class always extends a Profile class. When the program runs for the first time, Automapper finds the classes which inherit from Profile class and loads up the mapping configuration.

Automapper automatically maps the same named properties from source and destination.

Let's create a new folder called Mappings and add a new mapping class to it and name it SimpleMappings.cs.

namespace AutoMapper.Mappings
{
    public class SimpleMappings : Profile
    {

    }
}

Time to add the DTO folder and the Classes folder and we shall populate them with the appropriate classes:

//Department.cs
namespace AutoMapper.Classes
{
    public class Department
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Owner { get; set; }
        public string SecretProperty { get; set; } // You dont want to display this
    }
}

and here is the DTO class:

//DepartmentDTO.cs
namespace AutoMapper.DTO
{
    public class DepartmentDTO
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Owner { get; set; }
    }
}

With these in place, let’s go back and modify our MappingProfiles.cs:

//MappingProfiles.cs
namespace AutoMapper.Mappings
{
    public class MappingProfiles : Profile
    {
        public MappingProfiles()
        {
            CreateMap<Department, DepartmentDTO>().ReverseMap();
        }
    }
}

Note that specifying ReverseMap() allows us to map both ways.

Finally, time to add a new controller and let's call it MappingController:

//MappingController
namespace AutoMapper.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class MappingController : Controller
    {
        private readonly IMapper _mapper;
        private readonly Department sampleDepartment;

        public MappingController(IMapper mapper)
        {
            _mapper = mapper; //injected automapper

            //Initializing department object assume from a database
            sampleDepartment = new Department()
            {
                Name = "department1",
                Id = 1,
                Owner = "ABC",
                SecretProperty = "Very secret property"
            };
        }

        [HttpGet]
        public ActionResult<DepartmentDTO> Get()
        {
            return _mapper.Map<DepartmentDTO>(sampleDepartment);
        }
    }
}

Here is the result obtained from postman when called to localhost:<port>/api/mapping:

Auto_Mapper2

Our secret property is not shown meaning our automapper is working fine.

Getting Deeper

In the above example, it was a simple one to one mapping but automapper is also used for object flattening or making complex objects from a flattened object.

For example, let's consider a Person and personDTO object as the one below, the Person object has a property Address which is a type of Address object. Here, we are going to create a flattened object from complex object.

//Person.cs//Person.cs
namespace AutoMapper.Classes
{
    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
        public Address Address { get; set; }
    }
}

Address.cs class:

//Address.cs
namespace AutoMapper.Classes
{
    public class Address
    {
        public string HouseNumber { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
    }
}

PersonDTO.cs is going to contain the city property of the Address object only.

//PersonDTO.cs
namespace AutoMapper.DTO
{
    public class PersonDTO
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string City { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; } 
    }
}

Now, we have to head back to the mapping profile class and explicitly tell automapper to map the city property from Address's city property. This can be done with the help of ForMember which is shown below in the updated MappingProfiles.cs.

//MappingProfiles.cs
namespace AutoMapper.Mappings
{
    public class MappingProfiles : Profile
    {
        public MappingProfiles()
        {
            CreateMap<Department, DepartmentDTO>().ReverseMap();

            //Complex to Flattened
            CreateMap<Person, PersonDTO>()
                .ForMember(dest => dest.City,
                    opts => opts.MapFrom(
                        src => src.Address.City
                    )).ReverseMap();
        }
    }
}

Here is the complete MappingController:

namespace AutoMapper.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class MappingController : Controller
    {
        private readonly IMapper _mapper;
        private readonly Department sampleDepartment;
        private readonly Person samplePerson;

        public MappingController(IMapper mapper)
        {
            _mapper = mapper; //injected automapper

            //Initializing department object assume from a database
            sampleDepartment = new Department()
            {
                Name = "department1",
                Id = 1,
                Owner = "ABC",
                SecretProperty = "Very secret property"
            };

            //Initializing person object assume from a database
            samplePerson = new Person()
            {
                Firstname = "John",
                Lastname = "Doe",
                Age = 25,
                Sex = "Male",
                Address = new Address()
                {
                    City = "New York City",
                    HouseNumber = "10",
                    State = "NY",
                    ZipCode = "99999"
                }
            };
        }

        [HttpGet]
        public ActionResult<DepartmentDTO> Get()
        {
            return _mapper.Map<DepartmentDTO>(sampleDepartment);
        }

        [HttpGet]
        [Route("person")]
        public ActionResult<PersonDTO> GetPerson()
        {
            return _mapper.Map<PersonDTO>(samplePerson);
        }
    }
}

And finally, here is the output on postman:

Auto_Mapper3

The final DTO object is showing the city. Our mapping configuration worked!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here