Search code examples
c#deserializationautomapperjson-deserializationdto

How to map array of numbers to property inside a mapping table using AutoMapper


In my project I have:

StartUp.cs

var carDtos = JsonConvert.DeserializeObject<IEnumerable<CarDto>>(inputJson);
var cars = mapper.Map<IEnumerable<Car>>(carDtos);

Here I deserialize the JSON file using the DTO model, then try to map those models to the Car class. I get the error - Error mapping types.

Car.cs

public class Car
{
    public int Id { get; set; }

    public string Make { get; set; }

    public string Model { get; set; }

    public long TravelledDistance { get; set; }

    public ICollection<Sale> Sales { get; set; }

    public ICollection<PartCar> PartCars { get; set; } = new List<PartCar>();
}

CarDto.cs

public class CarDto
{
    public string Make { get; set; }

    public string Model { get; set; }

    public long TravelledDistance { get; set; }

    public ICollection<int> PartsId { get; set; }
}

cars.json

[ 
 {
     "make": "Opel",
     "model": "Astra",
     "travelledDistance": 516628215,
     "partsId": [
         39,
         62,
         72
     ]
 },
 {
     "make": "Opel",
     "model": "Astra",
     "travelledDistance": 156191509,
     "partsId": [
         48,
         44,
         112
     ]
 }
]

CarDealerProfile.cs

public class CarDealerProfile : Profile
{
    public CarDealerProfile()
    {          
        this.CreateMap<Car, CarDto>()
            .ForMember(dest =>
                dest.PartsId,
                opt => opt.MapFrom(src => src.PartCars));
    }
}

I know the code doesn't work because I am not mapping properly, but I just cant figure it out.

I want to map the numbers from the JSON array named partsId, through the mapping table PartCars located in the Car class and save those numbers as Ids for the Part class.


Solution

  • In your Profile you defined mapping from Car to CarDto but in your code you are trying to map from CarDto to Car. To be able to map both directions add ReverseMap(). Also you need to tell automapper how to convert int to PartCar and PartCar to int so it can map ICollection<PartCar> PartCars property to ICollection<int> PartsId property and vice versa. Try this:

    public class CarDealerProfile : Profile
    {
        public CarDealerProfile()
        {          
            CreateMap<Car, CarDto>()
               .ForMember(dest => dest.PartsId, opt => opt.MapFrom(src => src.PartCars))
               .ReverseMap();
            CreateMap<PartCar, int>().ConvertUsing(o => o.PartId);
            CreateMap<int, PartCar>().ConvertUsing(o => new PartCar { PartId = o });           
        }
    }