2

Is there a way to ignore mapping null values to destination globally (for all mapping configurations)?

Something that goes in here:

    //Automapper config
    Mapper.Initialize(cfg =>
    {
        //Initializes all mapping profiles in the assembly
        cfg.AddProfiles(Assembly.GetExecutingAssembly().GetName().Name);

        //If map is called without a profile creates default map
        cfg.CreateMissingTypeMaps = true;
    });

This is for instance mapping. Here is one example of what i'm trying to accomplish.

//Models
    class User {
      public string Name {get; set;}
      public string Email {get; set;}
      public string Password {get; set;}
    }

    class UserDto {
      public string Name {get; set;}
      public string Email {get; set;}
    }

//Start instances
     var user = new User { Name = "John", Email = "[email protected]", Password = "123"};

     var userDto = new UserDto { Name = "Tim" };
//Notice that we left the Email null on the DTO


//Mapping
    Mapper.Map(userDto, user);

The result ends up with the user having a null email. I want the user email to not be changed unless a new email is provided on the source (userDto). In other words ignore all null properties of all types on the source object from overwriting destination (User)

UPDATE: None of the answers below solve the problem. They simply do not work for collections. While the Autommaper figures out this bug I was able to get around my problem by using an ExpandoObject to filter out all null properties before mapping as below:

var patchInput = new ExpandoObject() as IDictionary<string, object>;

foreach (var property in userDto.GetType().GetProperties())
    if (property.GetValue(userDto) is var propertyValue && propertyValue != null)
        patchInput.Add(property.Name, propertyValue);

Mapper.Map(patchInput, user);
6
  • 1
    Possible duplicate of Automapper skip null values with custom resolver Commented Sep 26, 2017 at 14:24
  • Can you please add an example? Commented Sep 26, 2017 at 16:30
  • 1
    @Valerii Added the part where the config should go above. not sure if thats what you wanted. Commented Sep 26, 2017 at 17:25
  • @DonO Thanks. Can you also explain phrase "ignore mapping null values to destination". What behavior do you expect? Commented Sep 26, 2017 at 17:29
  • 1
    @Valerii just updated again hopefully it makes sense now. Commented Sep 26, 2017 at 17:55

1 Answer 1

1

It should work

Mapper.Initialize(cfg =>
        {
            cfg.AddProfiles(Assembly.GetExecutingAssembly().GetName().Name);
            cfg.CreateMissingTypeMaps = true;
            cfg.ForAllMaps((typeMap, map) =>
                map.ForAllMembers(option => option.Condition((source, destination, sourceMember) => sourceMember != null)));
        });
Sign up to request clarification or add additional context in comments.

8 Comments

This answers my question but it seems that the other conditions defined on individual mapping profiles no longer work. :\
@DonO It works for Nulable numbers like int?, for value types like int it won't work because value cannot be null.
@DonO For collections it is a defect in AutoMapper. For collections you can use my alternative solution. cfg.CreateMap<IEnumerable, IEnumerable>().ConvertUsing(new IgnoringNullValuesTypeConverter<IEnumerable>());
@DonO Why unaccepted? It works for example you provided.
@Valerri CreateMap<IEnumerable, IEnumerable>().ConvertUsing(new IgnoringNullValuesTypeConverter<IEnumerable>()); wont work because it needs to be IEnumerable<T> but the problem is the types of collections aren't the same.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.