Issue Seems like the condition gets ignored. Here is my scenario:
Source class
public class Source
{
public IEnumerable<Enum1> Prop1{ get; set; }
public IEnumerable<Enum2> Prop2{ get; set; }
public IEnumerable<Enum3> Prop3{ get; set; }
}
The enums subclass from a byte and are decorated with [Flags]. The destination class simply contains properties like Enum1, Enum2 and Enum3 containging the "total" bitwise value. So in essense if the Enumeration contains Enum1.value!, Enum1.Value2 and Enum1.Value3, the destination will contain the bitwise value of Enum1.Value1 | Enum1.Value2 | Enum1.Value3
Destination class
public Enum1 Prop1 { get; set; }
public Enum2 Prop2 { get; set; }
public Enum3 Prop3 { get; set; }
AutoMapper Mapping
Mapper.CreateMap<Source, Destination>()
.ForMember(m => m.Prop1, o =>
{
o.Condition(c => !c.IsSourceValueNull);
o.MapFrom(f => f.Prop1.Aggregate((current, next) => current | next));
})
.ForMember(m => m.Prop2, o =>
{
o.Condition(c => !c.IsSourceValueNull);
o.MapFrom(f => f.Prop2.Aggregate((current, next) => current | next));
})
.ForMember(m => m.Prop3, o =>
{
o.Condition(c => !c.IsSourceValueNull);
o.MapFrom(f => f.Prop3.Aggregate((current, next) => current | next));
});
The mapping works fine when the inner properties are not null and mapping succeeds and sets destination correctly. However, I want to skip the mapping when the member source value is null (when Prop1 is null, then skip the mapping).
I can see from debugging that Source.Prop1 is null. The condition gets completely ignored and get the exception saying the value is null.
Trying to map Source to Destination. Destination property: Prop1. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. --> Value cannot be null. Parameter name: source
I'm not sure if IsSourceValueNull checking for Prop1 or the the actual Source class which is not null. Only the member Prop1 is null.
Any help isappreciated.
IMO, this is actually a bug in AutoMapper's EnumMapper. The condition statements, as you have them above, should work fine. For example, when mapping from one concrete type to another the TypeMapMapper will correctly call the conditional:
Which eventually calls the defined condition:
But the
EnumMapper
doesn't call the TypeMap'sShouldAssignValue
method to find out if it should indeed map that field. Similarly, I don't see any reference toAfterMap
so it's unlikely that anything defined there is not going to work as well.I think you need to do the
Condition
andMapFrom
in two steps:The MapFrom will never be used if the Condition evaluates to false.
EDIT
Hmmm... That doesn't seem to work. I thought I had used that before somewhere. You could resort to just the MapFrom: