Skip to content

Mapping object with a null member to existing destination #4082

@Josephfilbert

Description

@Josephfilbert

Source/destination types

// Source types
private record Person
{
    public string Name { get; set; } = default!;
    public Address? TheAddress { get; set; }
}

private record Address
{
    public string Street { get; set; } = default!;
    public int Number { get; set; }
}

// Destination types
private record PersonModel
{
    public string Name { get; set; } = default!;
    public AddressModel? TheAddress { get; set; }
}

private record AddressModel
{
    public string Street { get; set; } = default!;
    public int Number { get; set; }
}

Mapping configuration

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<PersonModel, Person>();
    cfg.CreateMap<AddressModel, Address>();
});
Mapper = config.CreateMapper();

Version: 12.0.0

Expected behavior

Mapping PersonModel object with null TheAddress property to existing Person object with non-null TheAddress property, should make the property TheAddress in Person object to be null.

Actual behavior

Since version 12.0, TheAddress property in Person object no longer set to null. Previous version 11.0.1 still works as expected.

Steps to reproduce

var person = new Person
{
    Name = "Andy",
    TheAddress = new Address
    {
        Street = "Street 1",
        Number = 10
    }
};

var request = new PersonModel
{
    Name = "Charlie",
    TheAddress = null
};

Mapper.Map(request, person);
person.Name.Should().Be("Charlie");
person.TheAddress.Should().BeNull();
Full xUnit test code
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using FluentAssertions;

public class AutoMapperNestedClassMapTest
{
    private record Person
    {
        public string Name { get; set; } = default!;
        public Address? TheAddress { get; set; }
    }

    private record Address
    {
        public string Street { get; set; } = default!;
        public int Number { get; set; }
    }
    
    private record PersonModel
    {
        public string Name { get; set; } = default!;
        public AddressModel? TheAddress { get; set; }
    }

    private record AddressModel
    {
        public string Street { get; set; } = default!;
        public int Number { get; set; }
    }

    private static readonly IMapper Mapper;

    static AutoMapperNestedClassMapTest()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<PersonModel, Person>();
            cfg.CreateMap<AddressModel, Address>();
        });
        Mapper = config.CreateMapper();
    }

    [Fact]
    public void TestMapToExistingWhenSourceNull()
    {
        var person = new Person
        {
            Name = "Andy",
            TheAddress = new Address
            {
                Street = "Street 1",
                Number = 10
            }
        };

        var request = new PersonModel
        {
            Name = "Charlie",
            TheAddress = null
        };

        Mapper.Map(request, person);
        person.Name.Should().Be("Charlie");
        person.TheAddress.Should().BeNull();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions