Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper 4.2 not ignoring properties in profile

In my Web API controller method, before I map the UpdatePlaceDTO to PlaceMaster, I make a database call to populate the properties that are not covered by the Map but for some reason AutoMapper makes those properties null.

var mappedPlaceMaster = _mapper.Map<PlaceMaster>(placeMasterDTO);
// mappedPlaceMaster.EntityId is null 

I've tried many of the solutions to IgnoreExistingMembers but none of them work.

This is what I have

    public class PlaceMapperProfile : Profile
    {

        protected override void Configure()
        {
            // TO DO: This Mapping doesnt work. Need to ignore other properties
            //CreateMap<UpdatePlaceDto, PlaceMaster>()
            //    .ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
            //    .ForMember(d => d.Description, o => o.MapFrom(s => s.Description))
            //    .ForMember(d => d.ParentPlaceId, o => o.MapFrom(s => s.ParentPlaceId))
            //    .ForMember(d => d.LeftBower, o => o.MapFrom(s => s.LeftBower))
            //    .ForMember(d => d.RightBower, o => o.MapFrom(s => s.RightBower)).IgnoreAllNonExisting();
         }
     }

This is the extension

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
        {
            foreach (var property in expression.TypeMap.GetUnmappedPropertyNames())
            {
                expression.ForMember(property, opt => opt.Ignore());
            }
            return expression;
        }

I've used Modules to inject the mapper to my depedencies

protected override void Load(ContainerBuilder builder)
        {
            //register all profile classes in the calling assembly
            var profiles =
                from t in typeof(Navigator.ItemManagement.Data.MappingProfiles.PlaceMapperProfile).Assembly.GetTypes()
                where typeof(Profile).IsAssignableFrom(t)
                select (Profile)Activator.CreateInstance(t);

            builder.Register(context => new MapperConfiguration(cfg =>
            {
                foreach (var profile in profiles)
                {
                    cfg.AddProfile(profile);
                }


            })).AsSelf().SingleInstance();

            builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
                .As<IMapper>()
                .SingleInstance();
        }

I've seen in some thread that _mapper.Map actually creates a new object so how we make it to sort of "add-on" to the existing property values?

like image 217
Raihan Iqbal Avatar asked Oct 18 '22 09:10

Raihan Iqbal


1 Answers

Ok I found the solution. It was right in front of me but I didn't see it!

I just had to use an overload of the Map function which doesn't create a new instance of PlaceMaster rather it assigns the properties which are available in the map.

mappedPlaceMaster = _mapper.Map(placeMasterDTO, placeMasterFromDatabase);
like image 188
Raihan Iqbal Avatar answered Oct 21 '22 05:10

Raihan Iqbal