Question

Within my domain model for my view I have the following object that is serving as backing fields for my properties

public class ModelProperty<T>// where t:struct
{
    public T Value { get; set; }
    public string Description { get;  set; }
    public string LabelName { get;  set; }
}

The object in turn is presented as:

    public partial class Incident : BaseEntityModel
    {
        private ModelProperty<string> typeCode = new ModelProperty<string>{Description="1-C", LabelName =  "Type Code"};
        private ModelProperty<string> typeText = new ModelProperty<string>{Description="1-C", LabelName =  "Type Text"};

        public ModelProperty<string> TypeCode { get {return typeCode;}}
        public ModelProperty<string> TypeText { get {return typeText;}}
    }

The business object (my source) is not as complex.

public partial class Incident : ObjectBase
{
    public string TypeCode { get; set; }
    public string TypeText { get; set; }
}

is it possible to map the values from the source to the target. Using Automapper I have the following mapping setup

//note SrcObj is not an object but a namespace alias since the domain and business objects are of the same name
Mapper.CreateMap<SrcObj.Incident, Incident>()
                .ForMember(ui => ui.TypeText.Value,
                           opt => opt.MapFrom(src => src.TypeText));

But I am getting the exception Expression must resolve to top-level member and not any child object's properties. Use a custom resolver on the child type or the AfterMap option instead.

I'm new to automapper but in looking at the documentation is the object I am working with too complex (based on the idea that there are really three types here and not two)?

If it is possible to handle this type of mapping how is this done?

Update

Based upon the suggestion from Jimmy I have updated my code as follows:

Mapper.CreateMap<SrcObj.Incident, Incident>();
Mapper.CreateMap<string, ModelProperty<string>>()
                .ConvertUsing(src => new ModelProperty<string> { Value = src });

Mapper.AssertConfigurationIsValid();     
SrcObj.Incident viewModelDto = md.GenerateMockIncident(); //populate the business object with mock data    
uibase = Mapper.Map<SrcObj.Incident, Incident>(viewModelDto);

The code executes and I do not get any exceptions however the value that is being set and returned in the business object is still not getting assigned to the backing property Value it is still null.

What am I missing?

-cheers

Was it helpful?

Solution

An easier way is to create a type converter:

Mapper.CreateMap<string, ModelProperty<string>>()
    .ConvertUsing(src => new ModelProperty<string> { Value = src });

Then you'll have this for every time AutoMapper sees string -> ModelProperty. You won't have to do member-specific configuration at all.

OTHER TIPS

Try this.. you need to give a ModelProperty object mapping to the destination TypeText

Mapper.CreateMap<Funky.Incident, Incident>()
       .ForMember(ui => ui.TypeText,
                  opt => opt.MapFrom(src => 
                         new ModelProperty<string> 
                         { 
                          Value = src.TypeText 
                         }));

Do the same for the TypeCode property mapping so that all fields are mapped.

You need to account for each member mapping, only if their names are different OR if their type names are different. in this case, AutoMapper will have a hard time converting string to a Model object till you give hints.

Try mapping TypeCode as well.. And i don't know the properties of ObjectBase etc. So you need to do check if any manual mapping is needed there as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top