rbasniak
rbasniak

Reputation: 4954

Automapper forcing me to map every property

I have two classes like this:

public class RegistrationViewModel
{
    public string Password { get; set; }
    public string Username { get; set; }
    public List<string> Roles { get; set; }
}

public class ApplicationUser : IdentityUser
{

}

I want to map RegistrationViewModel to ApplicationUser, so here's the mapping configuration:

public class ViewModelToEntityMappingProfile : Profile
{
    public ViewModelToEntityMappingProfile()
    {
        CreateMap<RegistrationViewModel, ApplicationUser>().ForMember(au => au.UserName, map => map.MapFrom(vm => vm.Email));
    }
}

I added AutoMapper to the project in my Services.cs file:

services.AddAutoMapper();

What I'm expecting is that RegistrationViewModel.Roles is ignored during the mapping, since it doesn't exist in ApplicationUser, and that all other properties that exist in IdentityUser are set to their default values, since I RegistrationViewModel doesn't have them.

I'm calling the map like this:

var userIdentity = _mapper.Map<ApplicationUser>(model);

But this is generating the following exception:

An unhandled exception occurred while processing the request.

AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters ======================================================================================================================================== RegistrationViewModel -> ApplicationUser (Destination member list) Storefy.ServicesLayer.ViewModels.ViewModels.Authentication.RegistrationViewModel -> Storefy.BusinesLayer.Entities.Users.ApplicationUser (Destination member list)

Unmapped properties: AccessFailedCount EmailConfirmed LockoutEnabled LockoutEnd PhoneNumberConfirmed TwoFactorEnabled Id NormalizedUserName Email NormalizedEmail PasswordHash SecurityStamp ConcurrencyStamp PhoneNumber

It seems that AutoMapper is expecting all the properties in the IdentityUser to be mapped. This is my first time using AutoMapper, is this the expected behavior or am I missing something?

Upvotes: 0

Views: 3989

Answers (3)

rbasniak
rbasniak

Reputation: 4954

If anyone comes here in future, it turns out that my mapping configuration was in another project, and AutoMapper wasn't even reading it.

Instead of

services.AddAutoMapper()

in Services.cs I have to add AutoMapper to my project this way:

public void ConfigureServices(IServiceCollection services)
{
    ...

    var config = new AutoMapper.MapperConfiguration(cfg =>
    {
        cfg.AddProfile(new AutoMapperProfileConfiguration());
    });

    var mapper = config.CreateMapper();
    services.AddSingleton(mapper);

    ...
}

Upvotes: -1

Aspram
Aspram

Reputation: 653

AutoMapper has an extension method for ignoring properties. For example you can write like this:

CreateMap<RegistrationViewModel, ApplicationUser>()
     .ForMember(dest => dest.Roles, opt => opt.Ignore())

Upvotes: 3

Jamie Rees
Jamie Rees

Reputation: 8183

I faced the same issue so I wrote an extension method for this.

public static IMappingExpression<TSource, TDest> IgnoreAll<TSource, TDest>(this IMappingExpression<TSource, TDest> e)
{
    e.ForAllMembers(x => x.Ignore());
    return e;
}

Upvotes: 1

Related Questions