C# AutoMapper exception when mapping nullable byte to enum

.net, automapper, c#, enums, exception

Solution

Try using a `TypeConverter`. Something like this should work:

public class QualityControlStateTypeConverter
                           : TypeConverter<Nullable<byte>, QualityControlState>
{
    protected override QualityControlState ConvertCore(Nullable<byte> source)
    {
        return (source != null)
            ? (QualityControlState)Enum.Parse(typeof(QualityControlState),
                                              source.ToString())
            : QualityControlState.Ok;
    }
}

Use it in your mapping configuration like this:

Mapper.CreateMap<Nullable<byte>, QualityControlState>()
      .ConvertUsing(new QualityControlStateTypeConverter());

I tested it with this code and it seemed to work fine:

var qcs = Mapper.Map<Nullable<byte>, QualityControlState>(null); // OK
qcs = Mapper.Map<Nullable<byte>, QualityControlState>(0);        // OK
qcs = Mapper.Map<Nullable<byte>, QualityControlState>(1);        // Warning
qcs = Mapper.Map<Nullable<byte>, QualityControlState>(2);        // Error
qcs = Mapper.Map<Nullable<byte>, QualityControlState>(3);        // 3

Problem

I'm using AutoMapper (http://automapper.org/) to automatically map one object to the other. Source object: ``` public partial class SrcObject { public int Id { get; set; } ... public Nullable<byte> QcRea { get; set; } public Nullable<byte> QcPyg { get; set; } ... } ``` Destination object: ``` [DataContract] public class DstObject { [DataMember] public int Id { get; set; } ... [DataMember] public QualityControlState QcRea { get; set; } [DataMember] public QualityControlState QcPyg { get; set; } ... } ``` Enum: ``` public enum QualityControlState { Ok = 0, Warning = 1, Error = 2 } ``` Mappers: ``` Mapper.CreateMap<DateTime, Nullable<DateTime>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<float, Nullable<float>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<short, Nullable<short>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<QualityControlState, Nullable<byte>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<Nullable<byte>, QualityControlState>().ConstructUsing(MessageDtoConverter.ToQualityControlState); Mapper.CreateMap<byte, Nullable<byte>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<bool, Nullable<bool>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<int, Nullable<int>>().ConstructUsing(MessageDtoConverter.ToNullable); Mapper.CreateMap<SrcObject, DstObject>() .ForMember(d => d.RawResults, s => s.Ignore()) .ForMember(d => d.CorrectedImage, s => s.Ignore()) .ForMember(d => d.SegmentedImage, s => s.Ignore()) .ForMember(d => d.QcReaRotationAngleVertical, s => s.Ignore()) .ForMember(d => d.ReatoHCW, s => s.Ignore()); Mapper.AssertConfigurationIsValid(); ``` Mapping methods: ``` public static QualityControlState ToQualityControlState(Nullable<byte> value) { return (value != null) ? (QualityControlState)Enum.Parse(typeof(QualityControlState), value.ToString()) : QualityControlState.Ok; } public static Nullable<DateTime> ToNullable(DateTime value) { return (value != null) ? value : new DateTime(); } public static Nullable<float> ToNullable(float value) { return (value != null) ? value : 0.0f; } public static Nullable<short> ToNullable(short value) { return (value != null) ? value : (short)0; } public static Nullable<byte> ToNullable(QualityControlState value) { return (value != null) ? (byte)value : (byte)0; } public static Nullable<byte> ToNullable(byte value) { return (value != null) ? value : (byte)0; } public static Nullable<bool> ToNullable(bool value) { return (value != null) ? value : false; } public static Nullable<int> ToNullable(int value) { return (value != null) ? value : 0; } ``` Exception: ``` _innerException = {"Object reference not set to an instance of an object."} base {System.Exception} = {"\r\n\r\nMapping types:\r\nNullable`1 -> QualityControlState\r\nSystem.Nullable`1[[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> QualityControlState\r\n\r\nDestination path:\r... MemberName = "QcRea" SourceType = {Name = "Nullable`1" FullName = "System.Nullable`1[[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"} DestinationType = {Name = "QualityControlState" FullName = "QualityControlState"} ``` Seems like my custom Mapper for "Nullable to enum" is not called. Mapper.AssertConfigurationIsValid() has no problems. But why? And how do I convert this? Any ideas? Thank you

Original source