Steve
Steve

Reputation: 4483

How to use AutoMapper in Web Api in .Net Core?

Currently, I have this Web Api method which manually map my entity to DTO object and it works without issue. Now, I would like to implement AutoMapper which I have installed in registered in in ConfigureServices method and created the AutoMapper profile class and injected automapper in my Web Api controller constructor.

This is my manual mapping without AutoMapper

[HttpGet]
    public async Task<ActionResult<IEnumerable<MovieDto>>> GetMovies()
    {
        //manual mapping which can be replaced with Automapper
        var movies = (from m in _context.Movies
                      select new MovieDto()
                      {
                          Id = m.Id,
                          MovieTitle = m.MovieTitle,
                          ReleaseDate = m.ReleaseDate,
                          MovieStatus = m.MovieStatus,
                          PhotoFile = m.PhotoFile
                      }).ToListAsync();

        return await movies;

    }

and this is how I tried to add automapper to replace manual mapping.

[HttpGet]
public async Task<ActionResult<IEnumerable<MovieDto>>> GetMovies()
{
      return _mapper.Map<IEnumerable<MovieDto>>(_context.Movies);
}

But, it hits error Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<CinemaApp.NETCore31.WebAPI.Models.MovieDto>' to 'Microsoft.AspNetCore.Mvc.ActionResult<System.Collections.Generic.IEnumerable<CinemaApp.NETCore31.WebAPI.Models.MovieDto>>'

Upvotes: 2

Views: 4683

Answers (2)

Farhad Zamani
Farhad Zamani

Reputation: 5861

If you are using AutoMapper V9 you can use ProjectTo extensions method like this

private readonly IMapper _mapper;

public MovieController(IMapper mapper)
{
    _mapper = mapper;
}

[HttpGet]
public async Task<ActionResult<IEnumerable<MovieDto>>> GetMovies()
{
      return await _context.Movies
                .ProjectTo<MovieDto>(_mapper.ConfigurationProvider)
                .ToListAsync();
}

For using ProjectTo you need add AutoMapper.QueryableExtensions namespace.

Upvotes: 4

Steven Lemmens
Steven Lemmens

Reputation: 720

You will need to create a Profile and map all of the conversions you want to do. You don't have to do this field by field, you can just let AutoMapper figure it out as long as the names are the same.

This seems to be a good tutorial: https://code-maze.com/automapper-net-core/

First create a class that inherits from the Profile class in AutoMapper

public class MappingProfile : Profile 
{
   public MappingProfile()
   {
      CreateMap<Movie, MovieDto>();
   }
}

Note that if you ever want to map from MovieDto to Movie, you will have to create a second CreateMap line.

In your Startup.cs class, you need to register Automapper, and this will automatically scan for all profiles in the assembly that the Startup class is defined in with this code:

public void ConfigureServices(IServiceCollection services)
{
   services.AddAutoMapper(typeof(Startup));
}

Upvotes: 3

Related Questions