Reputation: 1271
I'm trying to figure out how to do this mapping in automapper 9.0.0. Can anybody help me out? I have these classes
class User
{
public string Name { get; set; }
public Address[] Addresses { get; set; }
}
class Address
{
public string StreetName { get; set; }
}
class UserDto
{
public string Name { get; set; }
public PropertiesDto Properties { get; set; }
}
class PropertiesDto
{
public AddressDto[] Addresses { get; set; }
}
class AddressDto
{
public string StreetName { get; set; }
}
My goal is to place the array of addresses inside a 'PropertiesDto' object, where there eventually will be a lot of other arrays.
var user = new User { Name = "Foo", Addresses = new[] { new Address { StreetName = "Main St." } } };
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address[], AddressDto[]>();
cfg.CreateMap<User, UserDto>()
.ForMember(d => d.Properties.Addresses, opt => opt.MapFrom(s => s.Addresses));
});
IMapper mapper = new Mapper(config);
var dtoUser = mapper.Map<UserDto>(user);
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(dtoUser));
Console.WriteLine("Hit enter...");
Console.ReadLine();
The code fails with this error message.
Unhandled exception. System.ArgumentException: Expression 'd => d.Properties.Addresses' must resolve to top-level member and not any child object's properties. You can use ForPath, a custom resolver on the child type or the AfterMap option instead. (Parameter 'lambdaExpression')
Upvotes: 0
Views: 666
Reputation: 1931
There is a special command for just this situation - if you're mapping to a property below the top level, then just use .ForPath
(as the error message suggests) in place of .ForMember
. Like this:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address[], AddressDto[]>();
cfg.CreateMap<User, UserDto>()
.ForPath(d => d.Properties.Addresses, opt => opt.MapFrom(s => s.Addresses));
});
Upvotes: 1
Reputation: 1271
What worked for me was using reverse mapping.
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<UserDto, User>()
.ForMember(d => d.Addresses, opt => opt.MapFrom(s => s.Properties.Addresses))
.ReverseMap();
});
Upvotes: 0