AutoMapper(v9&10)目标属性无对应源属性时映射未报错是否为Bug?
AutoMapper映射成功但配置验证报错,是Bug还是合理设计?
问题背景
按照AutoMapper文档的理解,当目标类型存在源类型没有的成员且未配置映射规则时,映射操作应该失败。但实际测试中出现矛盾现象:执行映射代码时成功完成,但调用配置验证方法时却抛出未映射成员的异常。
代码示例
实体类定义
public class OuterDest { public int Value { get; set; } public int AdditionalValue { get; set; } public DataClass1 DataClass { get; set; } public InnerDest Inner { get; set; } } public class InnerDest { public int OtherValue { get; set; } } public class OuterSource { public int Value { get; set; } public InnerSource Inner { get; set; } } public class InnerSource { public int OtherValue { get; set; } }
映射配置
Action<IMapperConfigurationExpression> mapperConfigExpression = cfg => { // 无论设置MemberList.Source还是Destination,结果一致 cfg.CreateMap<OuterSource, OuterDest>(); cfg.CreateMap<InnerSource, InnerDest>(); }; var mapperConfig = new MapperConfiguration(mapperConfigExpression); var mapper = mapperConfig.CreateMapper();
实际现象
- 执行映射代码
var mapped = mapper.Map<OuterDest>(source);时,映射成功完成,未抛出任何异常。 - 执行配置验证代码
mapperConfig.AssertConfigurationIsValid();时,抛出预期的未映射成员异常:
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 parametersOuterSource -> OuterDest (Destination member list)
AutoMapperConsole.TestClasses.Sources.OuterSource -> AutoMapperConsole.TestClasses.Destinations.OuterDest (Destination member list)Unmapped properties:
AdditionalValue
DataClass
解释与解决方案
这不是Bug,是AutoMapper的设计逻辑:
- 实际映射阶段:AutoMapper默认采用“宽容映射”策略,只会映射能找到对应规则的成员,未配置映射的目标成员会被设置为类型默认值(如int为0,引用类型为null),不会主动抛出异常。这种设计是为了提供灵活性,允许部分映射的场景。
- 配置验证阶段:
AssertConfigurationIsValid()是专门用于开发/测试阶段的校验工具,目的是强制确保映射配置的完整性,避免遗漏必要的映射规则,需要开发者主动调用才会生效。
如果希望在实际映射时也强制验证配置完整性,可以在配置中开启ValidateInlineMaps选项:
Action<IMapperConfigurationExpression> mapperConfigExpression = cfg => { cfg.ValidateInlineMaps = true; // 启用映射时的配置验证 cfg.CreateMap<OuterSource, OuterDest>(); cfg.CreateMap<InnerSource, InnerDest>(); };
开启后,执行mapper.Map<OuterDest>(source)时就会直接抛出未映射成员的异常,符合你预期的“映射失败”行为。
内容的提问来源于stack exchange,提问作者austinavmfb
相关产品推荐
相关产品推荐

