Using AutoMapper with ASP.NET Core

Couple of weeks back I started working on a simple ASP.NET Core & Angular 7 project on which I work after work and on the weekends.

The one and only purpose of it is to help me learn a few concepts and technologies I find important atm:

I currently have a basic authentication system built on IdentityServer – a completely separate project to help keep things as decoupled from each other as possible (see Clean Architecture).

Here we’ll see how easy it is to use AutoMapper to map our User entity into UserDto.

Why we might want to do that? Well, because we don’t want to give the user data she doesn’t actually need – we only give the user as much as she needs but not a bit more.

For example, let’s say that we are building a profile component that displays user’s information – first name, last name, street address, email and etc… If we use the User entity itself we are actually giving up too much information that isn’t needed, not to mention the security risks of returning, for example, password, token and etc…

That’s why we will use AutoMapper to map our User entity to another object that will return only a portion of the original User entity – the user’s id, first name, last name and username in our example.

Let’s first create our User entity

    public class User 
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Token { get; set; }
    }

That’s the model (entity) that’s going to represent a user in our system. As you see, here we have data that we shouldn’t return when there is a request – Token and Password.

We only want to return Id, Username, FirstName and LastName.

For this we’ll need to create another class – UserDto that will represent everything we want to return to the client and not a single bit more.

    public class UserDto
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

That’s it. We now have a type that will return only the information we want the client to be able to receive and nothing more.

Now, in order to use AutoMapper we need to install it via NuGet.

I assume you know how to use NuGet, so I am only going to provide you with the NuGet package name for AutoMapper:

AutoMapper.Extensions.Microsoft.DependencyInjection

After installing it, we need to configure it so that AutoMapper knows how and which types to map. To do that we need to create a config class which derives from Profile.

Let’s name that class MapperClass.cs and add the following:

    public class MapperConfig : Profile
    {
        public MapperConfig()
        {
            CreateMap<User, UserDto>();
        }
    }

Here, we are telling AutoMapper that we want to map User to UserDto. We are almost done.

What’s left for us to do is to tell .NET Core about AutoMapper and add it as a service. To do that we only have to add the following in our ConfigureServices, inside Startup.cs

services.AddAutoMapper();

We are done! Now, how could we use AutoMapper to map our User entity to UserDto? That’s pretty easy, actually.

Take a look at this basic snippet

public class ProfileController : Controller
{
    private readonly DatabaseContext _dbContext;
    private readonly IMapper _mapper;

    public ProfileController(DatabaseContext dbContext, IMapper mapper)
    {
        _dbContext = dbContext;
        _mapper = mapper;
    }

    [HttpGet("{profileId}")]
    public IActionResult GetSingleProfile([FromRoute] int profileId)
    {
        var user = _dbContext.Users.FirstOrDefault(x => x.Id == profileId);

        if (user == null)
        {
            return BadRequest("Invalid profile id");
        }

        var profileDto = _mapper.Map<UserDto>(user);

        return Json(profileDto);
    }
}

Here, we are getting a user by an id from our persistent store. Then, if the user exists, we map our User entity to our UserDto and return it as JSON.

Now the client (for example, an Angular app) only has access to the fields inside UserDto – id, first name, last name and username.

Happy coding!

Leave a Reply

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