Search code examples
c#automapper

Generate new object with mapping Automapper


I have a POST request in my controller Product like this:

[HttpPost("/product")]
public async Task<IActionResult> CreateProduct([FromBody] ProductRequest productCreate)
{
    var response = await _productService.CreateProduct(_mapper.Map<Product>(productCreate));
    return Ok(_mapper.Map<ProductResponse>(response));
}

ProductRequest has the following structure:

public class ProductRequest
{
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal? Price { get; set; }
}

I want to map this object ProductRequest to an object with Automapper named Product who has the following structure:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<ProductPrice> Prices { get; set; }
}

Where: ProductRequest.Name => Product.Name ProductRequest.Description => Product.Description

I know how to do that but I don't know how to use ProductRequest.Price and create a new instance of ProductPrice.Price.

ProductPrice has the following structure:

public class ProductPrice
{
    public int Id { get; set; }
    public int ProductId { get; set; }        
    public decimal Price { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
}

So when my Product reach the method Create in ProductService, this has a new object ProductPrice with the value of ProductRequest.Price in Product.ProductPrice.Price


Solution

  • You can try a mapping profile such as this using AfterMap and relying on the mapper internally to map both the outer object as well as the inner one:

    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            this.CreateMap<ProductRequest, ProductPrice>()
                .ForMember(p => p.StartDate, o => o.MapFrom(_ => DateTime.Now));
    
            this.CreateMap<ProductRequest, Product>()
                .AfterMap((request, product, context) =>
                {
                    product.Prices = new() { context.Mapper.Map<ProductPrice>(request) };
                });
        }
    }