AutoMapper: “Ignore the rest”?

2020-01-22 13:05发布

Is there a way to tell AutoMapper to ignore all of the properties except the ones which are mapped explicitly?

I have external DTO classes which are likely to change from the outside and I want to avoid specifying each property to be ignored explicitly, since adding new properties will break the functionality (cause exceptions) when trying to map them into my own objects.

16条回答
Explosion°爆炸
2楼-- · 2020-01-22 13:39

Version 5.0.0-beta-1 of AutoMapper introduces the ForAllOtherMembers extension method so you can now do this:

CreateMap<Source, Destination>()
    .ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
    .ForMember(d => d.Value, o => o.MapFrom(s => s.Id))
    .ForAllOtherMembers(opts => opts.Ignore());

Be aware that there is an advantage to explicitly mapping each property as you will never get problems of mapping failing silently that arise when you forget to map a property.

Perhaps in your case it might be wise to ignore all other members and add a TODO to come back and make these explicit after the frequency of changes to this class settle down.

查看更多
Fickle 薄情
3楼-- · 2020-01-22 13:39

The only infromation about ignoring many of members is this thread - http://groups.google.com/group/automapper-users/browse_thread/thread/9928ce9f2ffa641f . I think you can use the trick used in ProvidingCommonBaseClassConfiguration to ignore common properties for similar classes.
And there is no information about the "Ignore the rest" functionality. I've looked at the code before and it seems to me that will be very and very hard to add such functionality. Also you can try to use some attribute and mark with it ignored properties and add some generic/common code to ignore all marked properties.

查看更多
Summer. ? 凉城
4楼-- · 2020-01-22 13:40

How would you prefer to specify that certain members be ignored? Is there a convention, or base class, or attribute you would like to apply? Once you get into the business of specifying all the mappings explicitly, I'm not sure what value you'd get out of AutoMapper.

查看更多
仙女界的扛把子
5楼-- · 2020-01-22 13:43

From what I understood the question was that there are fields on the destination which doesn't have a mapped field in the source, which is why you are looking for ways to Ignore those non mapped destination fields.

Instead of implementing and using these extension method you could simply use

Mapper.CreateMap<destinationModel, sourceModel>(MemberList.Source);  

Now the automapper knows that it needs to only validate that all the source fields are mapped but not the other way around.

You can also use:

Mapper.CreateMap<destinationModel, sourceModel>(MemberList.Destination);  
查看更多
劫难
6楼-- · 2020-01-22 13:43

This seems an old question but thought I would post my answer for anyone else looking like I was.

I use ConstructUsing, object initializer coupled with ForAllMembers ignore e.g

    Mapper.CreateMap<Source, Target>()
        .ConstructUsing(
            f =>
                new Target
                    {
                        PropVal1 = f.PropVal1,
                        PropObj2 = Map<PropObj2Class>(f.PropObj2),
                        PropVal4 = f.PropVal4
                    })
        .ForAllMembers(a => a.Ignore());
查看更多
乱世女痞
7楼-- · 2020-01-22 13:46

I have updated Robert Schroeder's answer for AutoMapper 4.2. With non-static mapper configurations, we can't use Mapper.GetAllTypeMaps(), but the expression has a reference to the required TypeMap:

public static IMappingExpression<TSource, TDestination> 
    IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    foreach (var property in expression.TypeMap.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}
查看更多
登录 后发表回答