I got AutoMapperMappingException exception
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ---> System.InvalidCastException: Invalid cast from 'DummyTypes' to 'System.Nullable`1[[System.Int32, ...
when
public enum DummyTypes : int
{
Foo = 1,
Bar = 2
}
public class DummySource
{
public DummyTypes Dummy { get; set; }
}
public class DummyDestination
{
public int? Dummy { get; set; }
}
[TestMethod]
public void MapDummy()
{
Mapper.CreateMap<DummySource, DummyDestination>();
Mapper.AssertConfigurationIsValid();
DummySource src = new DummySource()
{
Dummy = DummyTypes.Bar
};
Mapper.Map<DummySource, DummyDestination>(src);
}
Should not AutoMapper map this implicitly without any extra explicit rule?
P.S. I cannot change the definition of DummyDestination.Dummy to enum. I have to deal with such interfaces.
It looks like no, it won't take care of this automatically for you. Interestingly, it will map an enum
to a regular int
.
Looking at AutoMapper's source, I think the problematic line is:
Convert.ChangeType(context.SourceValue, context.DestinationType, null);
Assuming context.SourceValue = DummyTypes.Foo
and context.DestinationType
is int?
, you would end up with:
Convert.ChangeType(DummyTypes.Foo, typeof(int?), null)
which throws a similar exception:
Invalid cast from 'UserQuery+DummyTypes' to
'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0
So I think really the question is why can't we cast a variable of type enum
to int?
That question has already been asked here.
This seems like a bug in AutoMapper. Anyway the workaround is to map the property manually:
Mapper.CreateMap<DummySource, DummyDestination>()
.ForMember(dest => dest.Dummy, opt => opt.MapFrom(src => (int?)src.Dummy));
Just in case if anyone want to try using a type converter
Mapper.CreateMap<int?, DummyTypes.Foo?>().ConvertUsing(new FooTypeConverter());
public class FooTypeConverter: TypeConverter<int?, DummyTypes.Foo?>
{
protected override DummyTypes.Foo? ConvertCore(int? source)
{
return source.HasValue ? (DummyTypes.Foo?)source.Value : null;
}
}
Cheers