Home > Back-end >  Nested collection mapping fails with automapper
Nested collection mapping fails with automapper

Time:10-11

Somehow the mapping fails with the error message:


One or more errors occurred. (The following member on Data.Shop cannot be mapped: Images Add a custom mapping expression, ignore, add a custom resolver, or modify the destination type Data.Shop.


After having spent some time tinkering with it and searching for a solution on the official documentation SO, I feel like I either messed up / forgot with a particular call in the profile, or need to resort to creating a custom map.. What do you guys think?

Configuration code that I used:

  • Entities
public class Shop
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public Specialty Specialty { get; set; } = new Specialty();

    public Address Address { get; set; } = new Address();

    public string Owner { get; set; }

    public List<Image> Images { get; set; } = new List<Image>();

    public List<Tag> Tags { get; set; } = new List<Tag>();

    public List<Promotion> Promotions { get; set; } = new List<Promotion>();
}
public class Image
{
    public Guid Id { get; set; }
    
    public string Title { get; set; }
    
    public byte[] ImageData { get; set; }
}
  • DTOs
public class ShopDto
{
    [Required]
    public Guid Id { get; set; }
    
    [Required]
    public string Name { get; set; }
    
    [Required]
    public string Specialty { get; set; }
    
    [Required]
    public int HouseNumber { get; set; }

    [Required]
    public string Street { get; set; }

    [Required]
    public string City { get; set; }

    [Required]
    public short Plz { get; set; }

    [Required]
    public string Owner { get; set; }

    public List<ImageDto> Images { get; set; } = new List<ImageDto>();

    public List<TagDto> Tags { get; set; } = new List<TagDto>();

    public List<PromotionDto> Promotions { get; set; } = new List<PromotionDto>();
}
public class ImageDto
{
    [Required]
    public Guid Id { get; set; }
    
    [Required]
    public string Title { get; set; }
    
    [Required]
    public byte[] ImageData { get; set; }
}
  • Profile code
CreateMap<Image, ImageDto>();
CreateMap<Shop, ShopDto>()
            .ForMember(dest => dest.City, member => member.MapFrom(source => source.Address.City))
            .ForMember(dest => dest.Plz, member => member.MapFrom(source => source.Address.Plz))
            .ForMember(dest => dest.Street, member => member.MapFrom(source => source.Address.Street))
            .ForMember(dest => dest.HouseNumber, member => member.MapFrom(source => source.Address.HouseNumber))
            .ForMember(dest => dest.Images, opt => opt.MapFrom(source => source.Images))
            .ReverseMap()
            .ForMember(src => src.Id, dest => dest.Ignore())
            .ForMember(src => src.Promotions, dest => dest.MapFrom(src => src.Promotions))
            .ForMember(src => src.Tags, dest => dest.MapFrom(src => src.Tags))
            .ForMember(src => src.Images, dest => dest.MapFrom(src => src.Images))
            .ForPath(src => src.Specialty.Name, dest => dest.MapFrom(src => src.Specialty))
            .ForPath(src => src.Address.City, dest => dest.MapFrom(src => src.City))
            .ForPath(src => src.Address.Plz, dest => dest.MapFrom(src => src.Plz))
            .ForPath(src => src.Address.Street, dest => dest.MapFrom(src => src.Street))
            .ForPath(src => src.Address.HouseNumber, dest => dest.MapFrom(src => src.HouseNumber));

CodePudding user response:

You have defined a mapping from Shop to ShopDto but appear to be attempting to map ShopDto to Shop. You need define mappings in both directions or swap the template arguments. Of course you also need a mapping from ImageDto to Image.

Additionally you can remove this part:

.ForMember(src => src.Images, dest => dest.MapFrom(src => src.Images))

AutoMapper is smart enough to map collections if it has a mapping for the collection element type.

  • Related