Skip to content

SrcObj with nullable long to DstObj with non nullable int throws InvalidOperationException: Nullable object must have a value #996

Description

@pedrobrasilborges

I have setup a custom long->int and long?->int? mappers to allow OverflowException, but when I set those up, going from SrcObj{long? prop} to DesObj{int prop}, throws an InvalidOperationException. This did not occur on version 10.0.8, only started to happen on 10.0.9. If I don't set those custom configs, the object mapping works as expected.

The source code:

var config = new TypeAdapterConfig();
config.NewConfig<long?, int?>().MapWith(src => src == null ? null : Convert.ToInt32(src.Value));
config.NewConfig<long, int>().MapWith(src => Convert.ToInt32(src));

var mapper = new Mapper(config);

void Test<TSrc, TDest>(string label, TSrc value)
{
    try
    {
        var result = mapper.Map<TDest>(value);
        Console.WriteLine($"  {label,-28}: OK     -> [{result}]");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"  {label,-28}: FAILED -> {ex.GetType().Name}: {ex.Message}");
    }
}

// Real Long value to Int conversion
Test<long, int>("long -> int (420000000000000)", 420000000000000L);
Test<long, int?>("long -> int? (420000000000000)", 420000000000000L);
Test<long?, int>("long? -> int (420000000000000)", (long?)420000000000000L);
Test<long?, int?>("long? -> int? (420000000000000)", (long?)420000000000000L);

Console.WriteLine();

config.NewConfig<PropSrc, PropDest>()
    .Map(dest => dest.IntNonNullable, src => src.LongNullable);
var mapperWithProp = new Mapper(config);

try
{
    var r1 = mapperWithProp.Map<PropDest>(new PropSrc { LongNullable = null });
    Console.WriteLine($"  {"Map() long?->int (null)",-28}: OK     -> [{r1.IntNonNullable}]");
}
catch (Exception ex)
{
    Console.WriteLine($"  {"Map() long?->int (null)",-28}: FAILED -> {ex.GetType().Name}: {ex.Message}");
}

try
{
    var r2 = mapperWithProp.Map<PropDest>(new PropSrc { LongNullable = 99 });
    Console.WriteLine($"  {"Map() long?->int (99)",-28}: OK     -> [{r2.IntNonNullable}]");
}
catch (Exception ex)
{
    Console.WriteLine($"  {"Map() long?->int (99)",-28}: FAILED -> {ex.GetType().Name}: {ex.Message}");
}

version 10.0.8 - working as expected

  long -> int (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long -> int? (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long? -> int (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long? -> int? (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.

  Map() long?->int (null)     : OK     -> [0]
  Map() long?->int (99)       : OK     -> [99]

version 10.0.9 - (long?)null -> int - throws exception

 long -> int (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long -> int? (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long? -> int (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.
  long? -> int? (420000000000000): FAILED -> OverflowException: Value was either too large or too small for an Int32.

  Map() long?->int (null)     : FAILED -> InvalidOperationException: Nullable object must have a value.
  Map() long?->int (99)       : OK     -> [99]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions