有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
您可以使用ForAllMembers,而不是只覆盖所需 像这样
public static IMappingExpression<TSource, TDest> IgnoreAll<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
{
expression.ForAllMembers(opt => opt.Ignore());
return expression;
}
小心,它将忽略所有,如果你不添加自定义映射,它们已经被忽略,将无法工作
我还想说,如果你有AutoMapper的单元测试。你测试了所有的模型,所有的属性映射正确,你不应该使用这种扩展方法
你应该显式地写ignore
其他回答
这是我编写的一个扩展方法,它忽略目标上所有不存在的属性。不确定它是否仍然有用,因为这个问题已经存在两年多了,但我遇到了同样的问题,必须添加大量手动忽略调用。
public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>
(this IMappingExpression<TSource, TDestination> expression)
{
var flags = BindingFlags.Public | BindingFlags.Instance;
var sourceType = typeof (TSource);
var destinationProperties = typeof (TDestination).GetProperties(flags);
foreach (var property in destinationProperties)
{
if (sourceType.GetProperty(property.Name, flags) == null)
{
expression.ForMember(property.Name, opt => opt.Ignore());
}
}
return expression;
}
用法:
Mapper.CreateMap<SourceType, DestinationType>()
.IgnoreAllNonExisting();
更新:显然,如果您有自定义映射,这不能正确工作,因为它会覆盖它们。我想如果先调用IgnoreAllNonExisting,然后再调用自定义映射,它仍然可以工作。
schdr有一个解决方案(作为这个问题的答案),它使用map . getalltypemaps()来找出哪些属性未映射并自动忽略它们。在我看来这是个更可靠的解决方案。
您希望如何指定忽略某些成员?是否有您想要应用的约定、基类或属性?一旦您开始显式地指定所有映射,我不确定您能从AutoMapper中得到什么价值。
这个问题已经问了几年了,但是这个扩展方法对我来说似乎更干净,使用当前版本的AutoMapper (3.2.1):
public static IMappingExpression<TSource, TDestination> IgnoreUnmappedProperties<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var typeMap = Mapper.FindTypeMapFor<TSource, TDestination>();
if (typeMap != null)
{
foreach (var unmappedPropertyName in typeMap.GetUnmappedPropertyNames())
{
expression.ForMember(unmappedPropertyName, opt => opt.Ignore());
}
}
return expression;
}
默认情况下,AutoMapper使用目标类型来验证成员,但您可以通过使用MemberList跳过验证。没有选择。
var configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Source2, Destination2>(MemberList.None);
);
你可以在这里找到参考资料
我已经更新了Can Gencer的扩展,不覆盖任何现有的地图。
public static IMappingExpression<TSource, TDestination>
IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof (TSource);
var destinationType = typeof (TDestination);
var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
foreach (var property in existingMaps.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
用法:
Mapper.CreateMap<SourceType, DestinationType>()
.ForMember(prop => x.Property, opt => opt.MapFrom(src => src.OtherProperty))
.IgnoreAllNonExisting();
更新:注意,在9.0版本Mapper静态API被删除