Click here to Skip to main content
15,880,796 members
Articles / Programming Languages / C#
Alternative
Article

Automapper Using .NET Core API 2.1

Rate me:
Please Sign up or sign in to vote.
4.84/5 (11 votes)
12 Aug 2018CPOL3 min read 49.7K   382   18   2
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:

C#
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:

C++
//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.

C#
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:

C#
//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:

C#
//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:

C#
//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:

C#
//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.

C#
//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:

C#
//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.

C#
//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.

C#
//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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student Indiana University
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionregarding automapper for api Pin
Member 1453477718-Jul-19 6:37
Member 1453477718-Jul-19 6:37 
Suggestion5 Star Pin
Sampath Lokuge22-Sep-18 1:12
Sampath Lokuge22-Sep-18 1:12 
Great intro about mapper. Thanks. It would be great if you can add a `post` method too.
My Latest Article : Basics of Node.js for MEAN Stack Development

Nothing is Impossible for Willing Heart.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.