IncludeMembers()
will always map from first match even if object is null
.
Let's say we have the following source models:
public class Item
{
public MovieMetadata MovieMetadata { get; set; }
public BookMetadata BookMetadata { get; set; }
}
public class MovieMetadata
{
public string Title { get; set; }
}
public class BookMetadata
{
public string Title { get; set; }
}
Destination model:
public class ItemDetail
{
public string Title { get; set; }
}
Mapping profile:
public class ItemProfile : Profile
{
public ItemProfile()
{
CreateMap<Item, ItemDetail>()
.IncludeMembers(
src => src.BookMetadata,
src => src.MovieMetadata);
CreateMap<BookMetadata, ItemDetail>();
CreateMap<MovieMetadata, ItemDetail>();
}
}
And Program class with instantiation and testing logic:
public class Program
{
public static void Main()
{
//create mapper
var configuration = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(ItemProfile));
});
var mapper = configuration.CreateMapper();
//check if configuration valid
mapper.ConfigurationProvider.AssertConfigurationIsValid();
Console.WriteLine("Mapper configuration is valid");
//try map book metadata
var bookItem = new Item
{
BookMetadata = new BookMetadata()
{
Title = "book"
},
MovieMetadata = null
};
var bookItemDetail = mapper.Map<ItemDetail>(bookItem);
bool isBookCorrectlyMapped = bookItem.BookMetadata.Title == bookItemDetail.Title;
Console.WriteLine($"Book mapped correctly: {isBookCorrectlyMapped}");
//try map movie metadata
var movieItem = new Item
{
BookMetadata = null,
MovieMetadata = new MovieMetadata()
{
Title = "movie"
}
};
var movieItemDetail = mapper.Map<ItemDetail>(movieItem);
bool isMovieCorrectlyMapped = movieItem.MovieMetadata.Title == movieItemDetail.Title;
Console.WriteLine($"Movie mapped correctly: {isMovieCorrectlyMapped}");
}
}
This is the output we will see:
Mapper configuration is valid
Book mapped correctly: True
Movie mapped correctly: False
We see that mapping for item with BookMetadata
succeeded, but for MovieMetadata
failed. Need to make updates so this test succeeds.
Suppose the reason it's failing is because of order of items in IncludeMembers()
:
.IncludeMembers(
src => src.BookMetadata,
src => src.MovieMetadata)
Here we have src.BookMetadata
first and src.MovieMetadata
second. During mapping it will find Title
field in src.BookMetadata
and will always use this value even if src.BookMetadata
is null
.
Is there any way to skip src.BookMetadata
if it is null
and use next src.MovieMetadata
instead? Or probably need to use something else instead of IncludeMembers()
?
Here is similar issue: https://github.com/AutoMapper/AutoMapper/issues/3204
Code above you can find here to quickly reproduce issue: https://dotnetfiddle.net/9YLGR6