Home > Enterprise >  AutoMapper - Get error when trying to map two classes
AutoMapper - Get error when trying to map two classes

Time:08-15

I am trying to use AutoMapper to map a DTO to an Entity class but I keep getting an error.

Here is the DTO Class:

public class Product
{
    public string ID { get; set; }
    public string SKU { get; set; }
    public string Name { get; set; }
    public PriceTiers PriceTiers { get; set; }
}

and here is the Entity:

public partial class Product
{
    public Product()
    {
        PriceTiers = new List<PriceTiers>();
    }

    [Key]
    public string ID { get; set; }
    public string SKU { get; set; }
    public string Name { get; set; }
    public virtual ICollection<PriceTiers> PriceTiers { get; set; }
}

Why do I keep getting the following error?

{"Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\nPriceTiers -> ICollection1\r\nWeb.Areas.DEAR.DTOs.PriceTiers -> System.Collections.Generic.ICollection1[[Web.Areas.DEAR.Data.PriceTiers, Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]\r\n\r\n Destination Member:\r\nPriceTiers\r\n"}

This is what I have in the Profile class:

AllowNullCollections = true;
CreateMap<DTOs.Product, Data.Product>();
CreateMap<DTOs.PriceTiers, Data.PriceTiers>();

and this is what I use to map the classes:

var products = _mapper.Map<IEnumerable<Product>>(result.Products);

This is what is in the Program.cs:

builder.Services.AddAutoMapper(typeof(AutoMapperProfiles).Assembly);

CodePudding user response:

The exception message is quite clear, the AutoMapper doesn't know how to map the data from DTOs.PriceTiers to ICollection<Data.PriceTiers>.


Solution 1: Map from DTOs.PriceTiers to ICollection<Data.PriceTiers>

I believe that Custom Type Converters is what you need.

  1. Create Custom Type Converters.
public class ICollectionDataPriceTiersTypeConverter : ITypeConverter<DTOs.PriceTiers, ICollection<Data.PriceTiers>>
{
    public ICollection<Data.PriceTiers> Convert(DTOs.PriceTiers src, ICollection<Data.PriceTiers> dest, ResolutionContext context)
    {
        if (src == null)
            return default;
    
        var singleDest = context.Mapper.Map<Data.PriceTiers>(src);
        
        return new List<Data.PriceTiers>
        {
            singleDest
        };
    }
}
  1. Add to mapping profile.
CreateMap<DTOs.PriceTiers, ICollection<Data.PriceTiers>>()
    .ConvertUsing<ICollectionDataPriceTiersTypeConverter>();

Demo @ .NET Fiddle


Solution 2: Map from ICollection<DTOs.PriceTiers> to ICollection<Data.PriceTiers>

If the PriceTiers in DTOs.Product supports multiple items and mapping with many to many (to ICollection<Data.ProductTiers>), then consider modifying the property as the ICollection<DTOs.PriceTiers> type.

namespace DTOs
{
    public class Product
    {
        ...
        public ICollection<PriceTiers> PriceTiers { get; set; }
    }
}

CodePudding user response:

Did you added "CreateMapper()" method after your configurations? Try something like that.

public class MappingProfile : Profile
{
    public MappingProfile {
        AllowNullCollections = true;
        CreateMap<DTOs.Product, Data.Product>();
        CreateMap<DTOs.PriceTiers, Data.PriceTiers>();
    }
}

After that, on your container service, inject this dependency:

var mappingConfig = new MapperConfiguration(cfg =>
{
    cfg.AddProfile(new MappingProfile());
});

IMapper mapper = mappingConfig.CreateMapper();
builder.Services.AddSingleton(mapper);
  • Related