I am facing a problem with my .NET CORE 2.1 code and AutoMapper for mapping DTOs to DomainModels and vice versa.
Originally I am using a CreateRequest DTO for creating data, which is mapped to my domain model. For update reasons I use an UpdateRequest DTO which derives from my CreateRequest DTO. There are some more properties on my UpdateRequest class which are also existing in my full domain model class.
Now I was able to reproduce a weird error while reading my model entity right after it has been created by the create request. Updating this read model with my UpdateRequest DTO using AutoMapper raises the following issue: A property named "VersionNumber" seems to be ignored, while other properties has been set successfully. It looks like AutoMapper saved the inherited class CreateRequest as the only existing map and is using it to map the derived class UpdateRequest also.
I have recreated this situation in LinqPad and add the used code here.
static bool init = false;
void Main()
{
init.Dump("IsInitialized");
if (!init)
{
// Configuration 1
AutoMapper.Mapper.Initialize(cfg => { cfg.CreateMissingTypeMaps = true; cfg.ValidateInlineMaps = false; });
// Configuration 2
// AutoMapper.Mapper.Initialize(cfg =>
// {
// cfg.CreateMap<Bar, Model>();
// // Configuration 2, also define map for the derived type
//// cfg.CreateMap<Foo, Model>();
// });
init = true;
}
// Create model and save db changes
Model created = AutoMapper.Mapper.Map<Model>(new Bar { Name="Bar" });
created.Dump("Created");
// Read model from db
var b = new Model { Name = created.Name, VersionNumber = created.VersionNumber };
// Create derived model to update read model
var f = new Foo { Name = "Foo", VersionNumber = 123 };
// Update entity
var result = AutoMapper.Mapper.Map(f, b);
b.Dump("Updated Bar");
result.Dump("Result = Updated Bar");
}
class Foo : Bar {
public long? VersionNumber {get; set;}
}
class Model {
public string Name {get; set;}
public long VersionNumber {get; set;}
}
class Bar {
public string Name {get;set;}
}
Further I have to explain my used configuration. Configuration 1 was my first attempt for just using a "dynamic" map configuration. Configuration 2 was used while testing this error. And finally the mapping will only work if you define both types, the base type and the derivation.
The result for 1 should be "VersionNumber" 123, instead it is 0. Same for 2, without defining it properly. Only using 2 with both mappings will bring up the expected result. All three configuration options work for the "Name" property.
In LinqPad I referenced the following version of AutoMapper: ....nuget\packages\automapper\7.0.1\lib\netstandard2.0
I would expect that an error occurs during the initial mapping of a dynamic configuration, or that AutoMapper recognizes that I want to map a derived type and therefore have to use a different map.