automapper profile do not work in api controller

I have two classes:

public class Parametro
{
    public int Id { get; set; }
    public string Nombre { get; set; }
    public int TipoDatoId { get; set; }
    public TipoDato TipoDato { get; set; }
}

public class ParametroCreateViewModel
{
    public string Nombre { get; set; }
    public int TipoDatoId { get; set; }
}

when I instate it in this way _mapper.Map (model); I get the following error:

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 ParametroCreateViewModel-> Parametro(Destination member list) ProyectoTest.ServiciosCliente.Application.Parametros.Commands.AddFParametro.ParametroCreateViewModel-> Calidda.ServiciosCliente.Domain.Parametros.Parametro(Destination member list) Unmapped properties: Id

but when I try it this way if it works: Mapper.Map < ParametroCreateViewModel,Parametro > (model);

My autofac is the following :

builder.RegisterAssemblyTypes().AssignableTo(typeof(Profile));
            builder.Register(c => new MapperConfiguration(cfg =>
            {
                foreach (var profile in c.Resolve<IEnumerable<Profile>>())
                {
                    cfg.AddProfile(profile);
                }
            })).AsSelf().SingleInstance();
            builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();

and my automapperconfig is:

public class AutoMapperConfig : Profile
{
    public static void Initialize()
    {
        Mapper.Initialize((config) =>
        {

config.CreateMap<ParametroCreateViewModel, Parametro>()
            .ForMember(dest => dest.Id, opt => opt.Ignore()).ReverseMap();
        }
     }
   }

and declare my global.asax:

AutofacConfig.Register();
AutoMapperConfig.Initialize();
GlobalConfiguration.Configure(WebApiConfig.Register);

Upvotes: 1

Views: 1067

Answers (1)

KozhevnikovDmitry
KozhevnikovDmitry

Reputation: 1720

Looks like here is a combination of several issues. You should load certain assembly with profile classes and also register them as Profile. In your example the foreach loop didn't perform any iterations, because container didn't contain any registrations for Profile. To create a mapping you should use profile itself instead of static Mapper class. Static method Initialize was not called, so mapping was not created. Please consider this example:

public class AutoMapperConfig : Profile
{
    public AutoMapperConfig()
    {
        // Create mapping within profile in constructor
        CreateMap<ParametroCreateViewModel, Parametro>()
            // ignore both unmapped properties
            .ForMember(dest => dest.Id, opt => opt.Ignore())
            .ForMember(dest => dest.TipoDato, opt => opt.Ignore())
            .ReverseMap();
    }
}

[Test]
public void AutoMapperAutofacTest()
{
    // Arrange
    var builder = new ContainerBuilder();

    // load certain assembly
    builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(AutoMapperConfig)))
            .AssignableTo<Profile>()
            .As<Profile>(); // register as profile
    builder.Register(c => new MapperConfiguration(cfg =>
    {
        foreach (var profile in c.Resolve<IEnumerable<Profile>>())
        {
            cfg.AddProfile(profile);
        }
    })).AsSelf().SingleInstance();
    builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();
    var container = builder.Build();

    var mapper = container.Resolve<IMapper>();

    var param = new Parametro();
    var viewModel = new ParametroCreateViewModel
    {
        Nombre = "Nombre",
        TipoDatoId = 1
    };

    // Act
    mapper.Map(viewModel, param);

    //Assert
    Assert.AreEqual(param.TipoDatoId, 1);
    Assert.AreEqual(param.Nombre, "Nombre");
}

I have wrapped the example with test to make it reproducable. Hope it helps.

Upvotes: 1

Related Questions