Home > Enterprise >  How to map array to array using Automapper in C#
How to map array to array using Automapper in C#

Time:12-06

I have below Source and Target class.

public class Source
    {
        public string BookName { get; set; }
        public Bookstore[] BookStore { get; set; }
    }

    public class Bookstore
    {
        public Address[] Address { get; set; }
    }

    public class Address
    {
        public string Street { get; set; }
    }

Target class as below

public class Target

    {
        public string Book { get; set; }
        public Store[] Store { get; set; }
    }
    public class Store
    {
        public Geo Geo { get; set; }
    }

    public class Geo
    {
        public Location[] Location { get; set; }
    }

    public class Location
    {
        public string Street { get; set; }
    }

I am looking for solution on proper mapping where source file data gets copied to target fields like below,

CreateMap<Source, Target>()
                .ForMember(dest => dest.Book, o => o.MapFrom(src => src.BookName));
               
CreateMap<Bookstore, Store>()
                .ForMember(dest => dest.Geo.Location, o => o.MapFrom(src => src.Address));

But I see a few errors like "resolve to top-level member" etc or Array fields, Geo and Location remains empty.

I would like to map source data to the destination.

Below is a source file example

var jsonText = @"                      
{
  "BookName": "Test",
  "BookStore": [
    {
      "Address": [
        {
          "Street": "1234"
        }
      ]
    }
  ]
}";


            var sourType = JsonConvert.DeserializeObject<Source>(jsonText);

The target file expected is as below, where "Geo" object is added,

{
  "Book": "Test",
  "Store": [
    {
      "Geo": {
        "Location": [
          {
            "Street": "1234"
          }
        ]
      }
    }
  ]
}

CodePudding user response:

You need a custom converter for this type of wrapping. Though your JSON result should be like this according to your model:

{
  "Book": "Test",
  "Store": [
    {
      "Geo": {
        "Location": [
          {
            "Street": "1234"
          }
        ]
      }
    }
  ]
}

Btw here is the solution:

Expression < Func < Bookstore, Store >> storeConverter = p => (new Store {
  Geo = new() {
    Location = p.Address
      .Select(ad => new Location {
        Street = ad.Street
      }).ToArray()
  }
});

CreateMap < Source, Target > ()
  .ForMember(dest => dest.Book, o => o.MapFrom(src => src.BookName))
  .ForMember(dest => dest.Store, o => o.MapFrom(src => src.BookStore));

CreateMap < Bookstore, Store > ()
  .ConvertUsing(storeConverter);

You can move the expression in a separate class type of converter for more cleaner code. see details in the documentation https://docs.automapper.org/en/stable/Custom-type-converters.html

  • Related