0

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.

Spell0
  • 51
  • 8
  • Dynamic maps work only in the simplest cases. In your case you should set CreateMissingTypeMaps to false and create all the needed maps. – Lucian Bargaoanu Apr 05 '19 at 11:32
  • Is this a bug or a known thing? I'm shocked that the dynamic map behaves so differently depending on if you made a map of a base-class before: https://gist.github.com/matthiaslischka/e9c3e91937f18cf3b98b133dceec3b99 – Matthias Apr 10 '19 at 05:52
  • I created an issue on github because I find this behavior very strange: https://github.com/AutoMapper/AutoMapper/issues/3025 – Matthias Apr 10 '19 at 07:04

0 Answers0