Automapper sets null in Collection properties not in source

38 Views Asked by At

I'm using AutoMapper 12.0.0 in an ASP.NET Core 6.0 project.

When I have a Collection like this:

public class Item
{
    public int Id { get; set; }
    public string? VideoUrl { get; set; }
    public ICollection<ItemTr> Translations { get; set; }
}

public class ItemTr 
{
    public int ParentId { get; set; }
    public Item Parent { get; set; }
    public string LanguageCode { get; set; }

    public string? Summary { get; set; }
    public string? Report { get; set; }
    public string? Incidences { get; set; }
}

Then I have a ModelView like this:

public class ItemView
{
    public int Id { get; set; }
    public List<ItemTrView> Translations { get; set; }
}

public class ItemTrView
{
    public int ParentId { get; set; }
    public string LanguageCode { get; set; }

    public string? Summary { get; set; }
    public string? Report { get; set; }
}

As you see, I'm missing the Incidences field in the model View, I don't need it.

I have the AUtomapper created like this:

    CreateMap<Item, ItemView>(MemberList.Source).ReverseMap();
    CreateMap<ItemTr, ItemTrView>(MemberList.Source).ReverseMap();

WHen reading I'm able to pass all the properties from Item to my model view ItemView and work with them.

The problem is when I try to save changes.

[HttpPost]
public IActionResult ReportsModalDo(ItemView model)
{
    var item = _unitOfWork.Item.Get(item);
    _mapper.Map(model, item);
    
    _unitOfWork.Complete();
}

It doesn't change any Item property, since those properties are not present in the SOURCE which is ItemView, and it does save the changes in the Translations Collection, so Summary and Report are changed properly BUT Incidences is set to null.

What I want is Incidences to remain as it is since there is no Incidences property in the source ItemTrView.

I have also tried to add a

.ForMember(x => x.Incidences, o => o.Ignore())

But it does nothing.

ANy idea? Am I missing anything here?

Thanks.

1

There are 1 best solutions below

0
Md Farid Uddin Kiron On

What I want is Incidences to remain as it is since there is no Incidences property in the source ItemTrView. Any idea? Am I missing anything here?

Well, according to your scenario, description and the shared code snippet it seems that, AutoMapper is overwriting the Incidences property with null because it's not present in the source ItemTrViewAutoMapper.

As you may know, AutoMapper uses a specific order for mapping properties. Since you've defined the mapping for both Item and ItemTr before ignoring the Incidences property, it might be overriding the configuration later.

In order to fix that, you could move the .ForMember(x => x.Incidences, o => o.Ignore()) configuration after both mappings for Item and ItemTr. So you can do as following:

CreateMap<ItemTr, ItemTrView>(MemberList.Source)
    .ForMember(x => x.Incidences, o => o.Ignore());

CreateMap<Item, ItemView>(MemberList.Source);

Or, you can use the ForAllMembers option to ignore the Incidences property within any nested collections. In that case, you can refactor like below:

CreateMap<ItemTr, ItemTrView>(MemberList.Source)
    .ForMember(x => x.Incidences, o => o.Ignore());

CreateMap<Item, ItemView>(MemberList.Source)
    .ForAllMembers(opts => opts.Condition((src, dest, member) => member.Name != "Incidences"));