asp.netasp.net-mvc-5asp.net-identityautomapperasp.net-identity-2

AutoMapper: Keep Destination Value if the property doesnt exists in source


I tried to search a lot, and try different options but nothing seems to work.

I am using ASP.net Identity 2.0 and I have UpdateProfileViewModel . When Updating the User info, I want to map the UpdateProfileViewModel to ApplicationUser (i.e. the Identity Model); but I want to keep the values, I got from the db for the user. i.e. the Username & Email address, that doesn't needs to change.

I tried doing :

Mapper.CreateMap<UpdateProfileViewModel, ApplicationUser>()
.ForMember(dest => dest.Email, opt => opt.Ignore());

but I still get the Email as null after mapping:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
user = Mapper.Map<UpdateProfileViewModel, ApplicationUser>(model);

I also tried this but doesn't works:

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var sourceType = typeof(TSource);
        var destinationType = typeof(TDestination);
        var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
        foreach (var property in existingMaps.GetUnmappedPropertyNames())
        {
            expression.ForMember(property, opt => opt.Ignore());
        }
        return expression;
    }

and then:

 Mapper.CreateMap<UpdateProfileViewModel, ApplicationUser>()
.IgnoreAllNonExisting();

Solution

  • All you need is to create a mapping between your source and destination types:

    Mapper.CreateMap<UpdateProfileViewModel, ApplicationUser>();
    

    and then perform the mapping:

    UpdateProfileViewModel viewModel = ... this comes from your view, probably bound
    ApplicationUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    Mapper.Map(viewModel, user);
    
    // at this stage the user domain model will only have the properties present
    // in the view model updated. All the other properties will remain unchanged
    // You could now go ahead and persist the updated 'user' domain model in your
    // datastore