Configure Automapper 9.0 in .Net Core

485 Views Asked by At

I followed the official documentation, stating the shift from static API as regards Automapper 9.0 but still I am unable to make it work inside my c# dotnet core App. I get the following exception:

"AutoMapperMappingException: missing type map configuration or unsupported mapping" in my controller class."

Can you show me please the configuration steps as regards Automapper 9.0?

Here the steps I performed:

Startup.cs

      var mappingConfig = new MapperConfiguration(mc =>
        {
           mc.AddProfile(new MyMapperProfile());
         });

   IMapper mapper = mappingConfig.CreateMapper();
   services.AddSingleton(mapper);

MyMapperProfile class

CreateMap<MasterData.Models.SupplierMaterial, SupplierMaterial>().
            ForMember(dto => dto.TechnicalDrawings, conf => conf.MapFrom(ol =>
                       ol.TechnicalDrawings.Select(v => v.Id)));

            CreateMap<MasterData.Models.WarehouseUbication, WarehouseUbication>().
            ForMember(dto => dto.MaterialCode, conf => conf.MapFrom(ol => ol.Material.Code));

            CreateMap<MasterData.Models.TechnicalDrawing, TechnicalDrawing>().
                ForMember(dto => dto.MaterialCode, conf => conf.MapFrom(ol => ol.Materials.Select(v => v.Code)))
               .ForMember(dto => dto.SupplierMaterialCode, conf => conf.MapFrom(ol => ol.SupplierMaterials.Select(v => v.Code)));

            CreateMap<MasterData.Models.MaterialDocument, MaterialDocument>().
                ForMember(dto => dto.Materials, conf => conf.MapFrom(ol => ol.Materials.Select(v => v.Code)));

            CreateMap<MasterData.Models.Material, Material>().
                ForMember(dto => dto.WarehouseUbications, conf => conf.MapFrom(ol => ol.WarehouseUbications.Select(v => v.Code)))
                .ForMember(dto => dto.SupplierMaterials, conf => conf.MapFrom(ol => ol.SupplierMaterials.Select(v => v.Code)))
                .ForMember(dto => dto.TechnicalDrawingID, conf => conf.MapFrom(ol => ol.TechnicalDrawing.Id))
                .ForMember(dto => dto.MaterialDocuments, conf => conf.MapFrom(ol => ol.MaterialDocuments.Select(v => v.Materials)));


            //var mapper = config.CreateMapper();

        }



    }
}

Controller class

public MaterialController(IMasterDataService masterService, IMapper mapper)
        {
            this.masterDataService = masterService;
            _mapper = mapper;
        }



  //[route]
     public List<Material> getAllMaterials()
      {
                List<Material> materialsList = new List<Material>();           

                foreach (MasterData.Models.Material m in masterDataService.GetMaterials())
                {
                    _mapper.Map<IEnumerable<Contracts.Material>>(m);
                }            

                return materialsList;
            }
3

There are 3 best solutions below

0
Jonas Høgh On BEST ANSWER

The error is in your controller code. You should either map directly from one collection type to another, using the built in collection mapping support, or map each element indiviually, building the target collection yourself. Currently, you're just discarding the mapped objects and returning an empty list.

public List<Material> getAllMaterials()
{
   var materialsList = _mapper.Map<List<Contracts.Material>>(masterDataService.GetMaterials())

   return materialsList;
}

or:

public List<Material> getAllMaterials()
{
  List<Material> materialsList = new List<Material>();           

  foreach (MasterData.Models.Material m in masterDataService.GetMaterials())
  {
     var mapped = _mapper.Map<Contracts.Material>(m);
     materialsList.Add(mapped);
  }            

  return materialsList;
}
1
AudioBubble On
public class MasterDataMapperProfile : Profile
{
    public MyMapperProfile()
    {
        CreateMap<MasterData.Models.SupplierMaterial, SupplierMaterial>().
            ForMember(dto => dto.TechnicalDrawings, conf => conf.MapFrom(ol => 
                       ol.TechnicalDrawings.Select(v => v.Id)));
    }
}

I think this should fix it. At the moment inside the profile you're creating a new config, registering your mapping on that config and then that config is discared.

Hope this helps

0
trailmax On

Your controller code should be like this

 public List<Material> getAllMaterials()
 {
            List<Material> materialsList = _mapper.Map<List<Contracts.Material>>(masterDataService.GetMaterials());

            return materialsList;
  }

Otherwise you are mapping a single object to a list. Also you are returning empty list.