AutoMapper映射含Original属性源到Record时抛出NullReferenceException
AutoMapper 12.0.1中Record类型与名为'Original'的源属性冲突的异常问题
问题详情
在使用AutoMapper 12.0.1版本时,若源类型包含名为Original的属性,且映射目标为record类型(而非class),会触发NullReferenceException。调用AssertConfigurationIsValid()方法后可发现,该Original属性被错误映射到了record的构造函数参数上,进而抛出AutoMapperConfigurationException。
经排查,问题根源在于C#编译器为record自动生成的复制构造函数。若尝试手动定义包含同类型参数的record主构造函数,会直接触发CS8910编译错误(编译器不允许显式定义与合成复制构造函数签名冲突的构造函数)。
复现测试代码(xUnit)
using AutoMapper; using Xunit; public class Source { public string? Original { get; set; } } public record Target; public class RecordMappingTests { [Fact] public void MapSourceWithOriginalPropertyToRecord_ThrowsException() { var config = new MapperConfiguration(cfg => cfg.CreateMap<Source, Target>()); // 调用该方法会触发AutoMapperConfigurationException config.AssertConfigurationIsValid(); var mapper = config.CreateMapper(); // 执行映射会触发NullReferenceException var target = mapper.Map<Target>(new Source()); } }
解决方法
以下7种方式可解决该问题:
- 将映射目标改为
class而非record类型 - 修改源类型中
Original属性的名称(避免与合成构造函数参数名冲突) - 为名为
original的构造函数参数显式映射为目标类型的null值,配置示例:cfg.CreateMap<Source, Target>() .ForCtorParam("original", opt => opt.MapFrom(src => (Target?)null)); - 将源类型中
Original属性的类型修改为目标record类型 - 为目标record添加与源属性类型一致的单参数主构造函数,示例:
public record Target(string? Original); - 为目标record添加与源属性类型一致的单参数构造函数(非主构造函数),示例:
public record Target { public Target(string? original) {} } - 配置AutoMapper忽略非公共构造函数,示例:
var config = new MapperConfiguration(cfg => { cfg.ShouldUseConstructor = ctor => ctor.IsPublic; cfg.CreateMap<Source, Target>(); });
Bug确认与建议
这是AutoMapper的一个Bug,建议提交GitHub Issue反馈。同时建议AutoMapper默认忽略record的编译器合成复制构造函数,避免此类因命名冲突导致的异常。
内容的提问来源于stack exchange,提问作者Scott Munro
相关产品推荐
相关产品推荐

