2

I'm pretty new using AutoMapper and i run into an issue

I have a model like this.

public class StepUp {
    public string Example {get;set;}
    public string Example2 {get;set;}
    public decimal? auxValue { get;set; }
}

But i have two ViewModels as destination

public class NuevoStepUpViewModel()
{
    public bool TieneAuxiliar { get; set; }
    public string Example { get;set; }
    public CargaDatosElectricos CargaDatosElectricos { get; set; }
}

public class CargaDatosElectricos {
    public CargaDatosElectricos(bool tieneAuxiliar)
    {
        TieneAuxiliar = tieneAuxiliar;
    }
    public readonly bool TieneAuxiliar;
    public string Example2 { get; set; }
}

I think some like this:

CreateMap<StepUp,NuevoStepUpViewModel()
    .ForMember(x => x.TieneAuxiliar, x => x.MapFrom(c => c.auxValue.HasValue))
    .ForMember(x => x.Example, x => x.MapFrom(c => c.Example))
    .ForMember(x => x.CargaDatosElectricos.Example2, x => x.MapFrom(c => c.Example2))
    .BeforeMap((x,y) => {
        x.CargaDatosElectricos = new CargaDatosElectricos(c.auxValue.HasValue);
    });

But i'm getting

Expression 'x => x.CargaDatosElectricos.Example2' must resolve to top-level member and not any child object's properties

How should i create my mapper configuration to do this type of mapping?

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
Juan Salvador Portugal
  • 1,233
  • 4
  • 20
  • 38
  • have you tried using automapper before? I mean, before your createMap, do another CreateMap for example2 – Iria Jan 17 '20 at 12:02
  • 1
    It may be resolved already, look at https://stackoverflow.com/questions/11633021/automapper-expression-must-resolve-to-top-level-member – Iria Jan 17 '20 at 12:03
  • Does this answer your question? [Automapper expression must resolve to top-level member](https://stackoverflow.com/questions/11633021/automapper-expression-must-resolve-to-top-level-member) – Iria Jan 17 '20 at 12:04

1 Answers1

2

There are some errors on your code. You could configure better your mapping using the AfterMap scope instead of BeforeMap to provide a complex configuration. (I am not sure but I think the) AutoMapper will not instance a property where the type is a class. So, you have to do it on the construtor of the destination class (VIewModel) or do it on AfterMap.

The TieneAuxiliar property will not allow you to set a value when it is readonly, so, you will not able to configure a map to this property. I change it to a public classic property.

See the working sample here:

https://dotnetfiddle.net/HSyUVv

using System;
using AutoMapper;

public class Program
{
    public static void Main()
    {
        var config = new MapperConfiguration(cfg => 
        {
            cfg.CreateMap<StepUp, NuevoStepUpViewModel>()
                .ForMember(vm => vm.TieneAuxiliar, opt => opt.MapFrom(e => e.auxValue.HasValue))
                .ForMember(vm => vm.Example, opt => opt.MapFrom(e => e.Example))
                .AfterMap((e, vm) => 
                          {
                              vm.CargaDatosElectricos.Example2 = e.Example2;
                          });
        });

        var mapper = config.CreateMapper();

        var stepUp = new StepUp()
        {
            Example = "Example 1",
            Example2 = "Example 2",
            auxValue = 10m
        };

        var viewModel = mapper.Map<StepUp, NuevoStepUpViewModel>(stepUp);

        Console.WriteLine("SteUp was converted to ViewModel");
        Console.WriteLine("TieneAuxiliar: {0}", viewModel.TieneAuxiliar);
        Console.WriteLine("Example: {0}", viewModel.Example);
        Console.WriteLine("CargaDatosElectricos.TieneAuxiliar: {0}", viewModel.CargaDatosElectricos.TieneAuxiliar);
        Console.WriteLine("CargaDatosElectricos.Exemple2: {0}", viewModel.CargaDatosElectricos.Example2);

    }

    public class StepUp 
    {
        public string Example { get; set; }
        public string Example2 { get; set; }
        public decimal? auxValue { get; set; }
    }

    public class NuevoStepUpViewModel
    {
        public bool TieneAuxiliar { get; set; }
        public string Example { get;set; }
        public CargaDatosElectricos CargaDatosElectricos { get; set; }

        public NuevoStepUpViewModel() 
        {
            this.CargaDatosElectricos = new CargaDatosElectricos();
        }
    }

    public class CargaDatosElectricos 
    {
        public CargaDatosElectricos()
        {
        }
        public bool TieneAuxiliar { get; set; }
        public string Example2 { get; set; }
    }
}
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194