Strange behavior of Automapper when property type

2019-08-17 15:38发布

问题:

After I saw how to ignore a property type with Automapper, I have tried it in a test project. It turns out that the property of a specific type is ignored properly, but when invoking AssertConfigurationIsValid() an exception is thrown, specifying that unmapped members were found. I can understand the reasoning of this exception, since the members of the type which should be ignored are not mapped, but what I am wondering is if this exceptions should be thrown in the context where I removed a mapping on purpose.

For the given code:

class Type1
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
}

class Type2
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public TypeToIgnore Prop3 { get; set; }
}

class MappingProfile : Profile
{
    public MappingProfile()
    {
        ShouldMapProperty = p => p.PropertyType != typeof(TypeToIgnore);
        CreateMap<Type2, Type1>();
    }
}

//...

var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile()));
config.AssertConfigurationIsValid(); //this throws AutoMapperConfigurationException

Wouldn't it be the correct behavior of Automapper to ignore the members and not throw an exception when verifying the validity of the configuration, as in the case of ignoring the property itself?

CreateMap<Type2, Type1>().ForMember(x => x.Prop3, y => y.Ignore());

回答1:

AutoMapper maps from source to destination. As far as I know by default fields present in source but missing in the destination type are ignored. What you have to explicitly handle are the fields missing in the source, but present in the destination type. In your case TypeToIgnore is in the source. Thus by ignoring that type, you have no source counterpart of Prop3 in the destination.

As an illustration, this will not throw exception:

ShouldMapProperty = p => p.PropertyType != typeof(TypeToIgnore);
CreateMap<Type1, Type2>();

Neither will this:

public class TypeToIgnore { }

void Main()
{

    var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile()));
    config.AssertConfigurationIsValid(); // won't throw
}

class Type1
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public bool Prop3 { get; set; } // <- because bool is ignored, you could simply delete this row
}

class Type2
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public TypeToIgnore Prop3 { get; set; }
    public long Prop4 { get; set; }
    public double Prop5 { get; set; }
}

class MappingProfile : Profile
{
    public MappingProfile()
    {
        ShouldMapProperty = p => p.PropertyType != typeof(bool);
        CreateMap<Type2, Type1>();
    }
}


标签: c# AutoMapper