0
votes

I have the following configuration.

public class AutoMapperProfile: Profile
    {
        public AutoMapperProfile()
        {
           CreateMap<DTO, Model>();
           CreateMap<InnerDTO, NavigationPropertyModel>();
        }
   }

In my code I have

Model.NavigationProperty = mapper.Map(DTO.InnerDTO, Model.NavigationProperty);

seems to work very well but

Model = mapper.Map(DTO, Model);

doesn't. (InnerDTO isn't mapped)

PS: mapper is an instance of the automapper.

I want to stick with the second approach since the DTO can have more properties than just the InnerDTO.

I tried using Mapper.AssertConfigurationIsValid(); but got an exception

System.InvalidOperationException: 'Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.'

2
Maybe I got your question wrong but with automapper, as long as you define the mappings for all properties you have, which could be properties of the others, automapper knows how to map them correctly. You don't need to manually call Model.NavigationProperty = mapper.Map(). - David Liang
-1 downvoted because you have not provided a How to create a Minimal, Complete, and Verifiable example. You have not provided how mapper was instantiated nor the definitions of your models. - Erik Philips
@ErikPhilips I could reproduce this behavior with a general Model with NavigationProperty. Wait for op to check whether my answer will work. - Edward

2 Answers

0
votes

Try to configure sub-property for CreateMap<DTO, Model>();.

        public AutoMapperProfile()
    {
        CreateMap<DTO, Model>()
            .ForMember(dest => dest.NavigationPropertyModel, opt => opt.MapFrom(src => src.InnerDTO));
        CreateMap<InnerDTO, NavigationPropertyModel>();
    }
-1
votes

Possibly what you are missing is to add your AutoMapperProfile class in Startup.cs.

public void ConfigureServices(IServiceCollection services) {
    // Automapper conf
    var config = new MapperConfiguration(configure => {
        // Add your profile class here
        configure.AddProfile(new AutoMapperProfile());
    });
    // Creating instance of automapper for dependency injection
    var mapper = config.CreateMapper();
    services.AddSingleton(mapper);

    // More complex code here...
}

Subsequently, by dependency injection, you use automapper. In my particular case, I do it in the following way:

[Route("api/Permiso")]
[ApiController]
public class PermisoController : ControllerBase {
    private readonly IMapper _mapper;
    private readonly IBusinessLogicHelper _blh;

    public PermisoController(BusinessLogicHelper blh, IMapper mapper) {
        _blh = blh;
        _mapper = mapper;
    }

    [HttpGet]
    public IActionResult Get() {
        try {
            // Get raw data from entities
            var resultsRaw = _blh.GetDataRaw();
            if (resultsRaw == null) {
                return NotFound();
            }
            // Mapping data from entity to DTO
            var resultsDTO = _mapper.Map<ReturnDataDTO>(resultsRaw);
            return Ok(resultsDTO);
        } catch (Exception ex) {
            // Custom ObjectResult for InternalServerError
            return new InternalServerErrorObjectResult(ex.Message);
        }
    }
}