automapper v10+必须显式创建imapper实例,禁用静态mapper;需配置createmap并调用assertconfigurationisvalid()校验,推荐使用profile类组织映射逻辑。

AutoMapper 初始化必须调用 CreateMapper() 或 Mapper.Initialize()
新版 AutoMapper(v10+)已移除静态 Mapper 类,直接调用 Mapper.Map<t>()</t> 会抛出 System.NullReferenceException: 'Object reference not set to instance of an object.'。必须显式创建 IMapper 实例。
- 推荐在
Program.cs(.NET 6+)或Startup.cs中配置:
var mapperConfig = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Source, Destination>();
});
IMapper mapper = mapperConfig.CreateMapper(); // 关键:不能省略
- 若用依赖注入(如 ASP.NET Core),应注册为单例:
services.AddAutoMapper(cfg => cfg.CreateMap<Source, Destination>()); // 自动发现 Profile 更安全
- 手动 new
MapperConfiguration后忘记调用CreateMapper()是最常见空引用原因
CreateMap<tsource tdestination>()</tsource> 默认只映射同名同类型的属性
AutoMapper 不会自动转换类型或处理嵌套对象,比如 DateTime → string、List<int></int> → int[]、或 User.Profile.Name → UserDto.ProfileName,这些都需要显式配置。
- 基础映射(字段名和类型完全一致)可直接使用:
cfg.CreateMap<User, UserDto>(); // Name → Name, Id → Id ✅
- 字段名不同需用
ForMember:
cfg.CreateMap<User, UserDto>()
.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.FirstName + " " + src.LastName));
- 忽略某字段用
Ignore():
.ForMember(dest => dest.PasswordHash, opt => opt.Ignore())
- 嵌套对象默认不递归映射,需单独声明
CreateMap:
cfg.CreateMap<UserProfile, UserProfileDto>();
cfg.CreateMap<User, UserDto>()
.ForMember(u => u.Profile, opt => opt.MapFrom(x => x.Profile));
运行时出现 AutoMapper.AutoMapperMappingException 的典型原因
这个异常通常包裹更具体的子错误,直接看 InnerException 或 Message 才能定位。常见触发点有:
- 目标类型无公共无参构造函数(如
record在旧版 AutoMapper 中可能失败,v12+ 支持更好) - 源/目标属性类型不兼容且未配置
ConvertUsing或MapFrom - 循环引用未启用
cfg.AllowNullCollections = true或未配置PreserveReferences() - 使用了
MapFrom但 lambda 访问了 null 源属性(例如src.Address.Street而src.Address为 null)→ 应改用UseValue或前置空判断
调试建议:在 MapperConfiguration 构造后立即调用 AssertConfigurationIsValid(),它会在启动时主动校验所有映射规则是否可执行:
var config = new MapperConfiguration(cfg => { /* ... */ });
config.AssertConfigurationIsValid(); // 抛出明确的验证失败信息
Profile 类更适合中大型项目,避免配置散落在 Startup 中
把映射规则封装进继承自 Profile 的类,能解耦、复用、便于单元测试。AutoMapper 会自动扫描程序集中所有 Profile 子类(前提是用了 AddAutoMapper(Assembly))。
- 定义一个 Profile:
public class UserMappingProfile : Profile
{
public UserMappingProfile()
{
CreateMap<User, UserDto>()
.ForMember(d => d.CreatedAt, o => o.ConvertUsing<DateTimeToIsoStringConverter>());
}
}
- 注册时传入程序集:
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
- 自定义转换器需实现
ITypeConverter<tsource tdestination></tsource>,比在CreateMap里写 lambda 更易测试和复用
Profile 不是语法糖,它是组织映射逻辑的实际边界——尤其当多个 DTO 共享同一组转换规则时,漏掉一个 CreateMap 或错放 Profile 到未被扫描的程序集,就会静默失败。









