dotnetlooper
dotnetlooper

Reputation: 51

Receiving AutoMapperMappingException

Currently I'm creating a new feature. It looks simple, but I am stuck at a problem with automapping dto to another one.

I have to create a wishlist [adding /deleting items of wishlist].

All works fine, except one thing: while adding an item to the wishlist, I'm get a message like this:

"type": "AutoMapperMappingException",
"message": "Error mapping types..."

However, I can see it got inserted into the database. Also, can delete it too. I understand the problem is linked to Automapper, but I could not figure out how to map correctly.

[HttpPost]
public async Task<IActionResult> Add(WishListItemCreationDto wishListItemDto)
{
    var itemAdd = _mapper.Map<WishlistItemDto>(wishListItemDto);
    var itemCreated = await _wishListItemService.AddAsync(itemAdd);

    return CreatedAtAction(nameof(GetId), new { id = itemCreated.Id }, wishListItemDto);
}
  
//service
public async Task<WishlistItemDto> AddAsync(WishlistItemDto item)
{
    var entity = _mapper.Map<WishlistItem>(item);
    var entityDetails = await _productDetailsRepository.GetById(item.ProductDetailId);
    entity.ProductDetails = entityDetails;
    await _wishListItemRepository.AddAsync(entity);

    return _mapper.Map<WishlistItemDto>(entity);
}

DTOs:

public class WishListItemCreationDto
{
        [Required]
        public string CustomerId { get; set; }

        [Required]
        public int ProductDetailId { get; set; }

        [Min(1)]
        [Required]
        public int Quantity { get; set; }
}

public class WishlistItemDto
{
        public int Id { get; set; }
        public string CustomerId { get; set; }
        public int ProductDetailId { get; set; }

        public ProductDetailsDtoWithPrimaryImage ProductDetails { get; set; }

        public int Quantity { get; set; }
}

public class WishlistItem
{
        public int Id { get; set; }
        public string CustomerId { get; set; }
        public Customer Customer { get; set; }
        public int ProductDetailsId { get; set; }
        public ProductDetails ProductDetails { get; set; }
        public int Quantity { get; set; }
}

ProductDetails DTO:

public class ProductDetails
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public Product Product { get; set; }

    public IList<ProductAttributeValue> ProductAttributes { get; set; } = new List<ProductAttributeValue>();

    public int Quantity { get; set; }
    public string Sku => $"BRD{Id}";
    public byte[] RowVersion { get; set; } = new byte[0];
}

public class ProductDetailsDtoWithPrimaryImage
{
    public int Id { get; set; }
    public int Quantity { get; set; }
    public int ProductId { get; set; }

    public ProductDisplayEntity Product { get; set; }

    public IEnumerable<ProductAttributeWithValueDto> ProductAttributes { get; set; }

    public byte[] RowVersion { get; set; }
    public string Sku => $"BRD{Id}";
    public int? PrimaryImageId { get; set; }
}

AutoMapper:

public WishlistItemProfile()
{
    CreateMap<WishlistItem, WishListItemCreationDto>().ReverseMap();
    CreateMap<WishlistItemDto, WishListItemCreationDto>().ReverseMap();
    CreateMap<WishlistItem, WishlistItemDto>()
                .ForMember(wi => wi.ProductDetailId, opt => opt.MapFrom(f => f.ProductDetailsId))
                .ForMember(wi => wi.ProductDetails, opt => opt.MapFrom(f => f.ProductDetails))
                .ReverseMap();
}

Upvotes: 0

Views: 62

Answers (1)

DarkSideMoon
DarkSideMoon

Reputation: 1063

everything is okay, but you missed inner mapping of your classes.

What the error says:

Mapping types:
ProductDetailsDtoWithPrimaryImage -> ProductDetails
SimpleWebApi.Controllers.ProductDetailsDtoWithPrimaryImage -> SimpleWebApi.Controllers.ProductDetails

Add additional mapping in your constructor WishlistItemProfile

CreateMap<ProductDetails, ProductDetailsDtoWithPrimaryImage>().ReverseMap();

And it starts works perfect

Upvotes: 1

Related Questions