Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper: How to map only matching property names and ignore all others?

I am new to AutoMapper and using version 6.2.2. I am trying to map a view model to an entity (also using Entity Framework). I want to update only the properties that exist in both the viewmodel and the entity. The entity has other navigational properties and related objects that are not part of the source viewmodel. I am currently getting an error that I have unmapped properties on the destination entity. Both my viewmodel and entity have over 40 properties so I do not want to explicitly add each one to the map.

Here is my code:

Map:

public static void RegisterMaps()
{
    AutoMapper.Mapper.Initialize(config =>
    {
                    config.CreateMap<EditApplicationViewModel, Application>();

    });

}

I have also tried the following but get the same error:

config.CreateMap<EditApplicationViewModel, Application>(MemberList.source);

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditApplicationViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        Application application = _applicationService.GetById(viewModel.ApplicationId);

        application = Mapper.Map(viewModel, application);
    }
}

Error Message:

InnerException: HResult=-2146233088 Message= 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 ========================================================== String -> User (Destination member list) System.String -> ..***.entities.User (Destination member list)

Unmapped properties: removed - a very long list of related objects and properties on the destination

   Source=AutoMapper
   StackTrace:
        at lambda_method(Closure , EditApplicationViewModel , Application , ResolutionContext )

UPDATE:

I have also tried the following map. I am not receiving any errors but none of the source properties are updated on the destination.

config.CreateMap<EditApplicationViewModel, Application>().ForAllOtherMembers(opts=>opts.Ignore());
like image 868
Rokal Avatar asked May 04 '18 14:05

Rokal


1 Answers

I was able to solve my problem and it had nothing to do with ignoring properties that didn't match by name between source and destination. It appears that the default behavior of AutoMapper already ignores these properties by default.

The error message was very deceiving:

  InnerException: 
       HResult=-2146233088
       Message=
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
==========================================================
String -> User (Destination member list)
System.String -> ***.***.***.entities.User (Destination member list)

The actual cause of my problem was a type mismatch. I have a string property in the view model called CreatedByUser. I also had a navigational property on my entity called CreatedByUser of type User.

I had to explicitly ignore this property in the CreateMap.

 config.CreateMap<EditApplicationViewModel, Application>()
                    .ForMember(d => d.CreatedByUser, opt => opt.Ignore());

No other directives were required to ignore any other properties that didn't exist on either source or destination.

Again, the error message I received "Unmapped members were found." through me off. The actual problem was a type mismatch.

like image 80
Rokal Avatar answered Sep 28 '22 06:09

Rokal