有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
默认情况下,AutoMapper使用目标类型来验证成员,但您可以通过使用MemberList跳过验证。没有选择。
var configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Source2, Destination2>(MemberList.None);
);
你可以在这里找到参考资料
其他回答
这似乎是一个老问题,但我想我会把我的答案贴出来给那些长得像我的人。
我使用ConstructUsing,对象初始化器加上ForAllMembers忽略例如
Mapper.CreateMap<Source, Target>()
.ConstructUsing(
f =>
new Target
{
PropVal1 = f.PropVal1,
PropObj2 = Map<PropObj2Class>(f.PropObj2),
PropVal4 = f.PropVal4
})
.ForAllMembers(a => a.Ignore());
这个问题已经问了几年了,但是这个扩展方法对我来说似乎更干净,使用当前版本的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;
}
版本12 这是一个非常糟糕的代码,但它解决了紧急工作。
CreateMap<RepairPutRequest, Repair>(MemberList.None)
.ForAbdusselamMember(x => x.ClosedLostTimeId, y => y.MapFrom(z => z.ClosedLostTimeId))
.ForAbdusselamMember(x => x.Explanation, y => y.MapFrom(z => z.Explanation)).IgnoreUnmapped()
;
public static class MappingExtensions
{
public static Dictionary<string, List<string>> list = new Dictionary<string, List<string>>();
public static IMappingExpression<TSource, TDestination> IgnoreUnmapped<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var key =$"{sourceType.FullName}__||__{destinationType.FullName}" ;
var t = list[key];
foreach (var item in destinationType.GetProperties())
{
if (!t.Contains(item.Name)) {
expression.ForMember(item.Name, x => x.Ignore());
}
}
return expression;
}
public static IMappingExpression<TSource, TDestination> ForAbdusselamMember<TSource, TDestination, TMember>(this IMappingExpression<TSource, TDestination> expression,
Expression<Func<TDestination, TMember>> destinationMember, Action<IMemberConfigurationExpression<TSource, TDestination, TMember>> memberOptions )
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var key = $"{sourceType.FullName}__||__{destinationType.FullName}";
if (!list.ContainsKey(key))
{
list[key]=new List<string>();
}
expression.ForMember(destinationMember, memberOptions);
var memberInfo = ReflectionHelper.FindProperty(destinationMember);
list[key].Add(memberInfo.Name);
return expression;
}
}
我已经能够做到这一点的方式如下:
Mapper.CreateMap<SourceType, DestinationType>().ForAllMembers(opt => opt.Ignore());
Mapper.CreateMap<SourceType, DestinationType>().ForMember(/*Do explicit mapping 1 here*/);
Mapper.CreateMap<SourceType, DestinationType>().ForMember(/*Do explicit mapping 2 here*/);
...
注意:我使用的是AutoMapper v.2.0。
对于Automapper 5.0,为了跳过所有未映射的属性,你只需要放
.ForAllOtherMembers(x=>x.Ignore());
在你资料的最后。
例如:
internal class AccountInfoEntityToAccountDtoProfile : Profile
{
public AccountInfoEntityToAccountDtoProfile()
{
CreateMap<AccountInfoEntity, AccountDto>()
.ForMember(d => d.Id, e => e.MapFrom(s => s.BankAcctInfo.BankAcctFrom.AcctId))
.ForAllOtherMembers(x=>x.Ignore());
}
}
在这种情况下,只有Id字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!