ASP.NET Core如何配置AutoMapper触发Car模型的ArgumentOutOfRangeException?
解决AutoMapper映射时模型验证异常被包装的问题
问题分析
AutoMapper在执行属性映射过程中,会自动把目标对象属性设置时抛出的异常包装为AutoMapperMappingException,导致原本期望由Car模型Description属性触发的ArgumentOutOfRangeException无法直接抛出,而是被包裹在AutoMapper的异常里。
解决方案:用ConstructUsing创建实例 + AfterMap手动赋值
修改CarProfile配置,先通过构造函数创建Car实例,再手动设置Description属性。这样模型的验证逻辑会直接触发,抛出的原始异常不会被AutoMapper包装。
修改后的CarProfile代码:
using AutoMapper; using MyNamespace.AppService.Contract.Cars; using MyNamespace.Model.Cars; namespace MyNamespace.AppService.Profiles; public class CarProfile: Profile { public CarProfile() { CreateMap<CarDto, Car>() // 调用Car的构造函数创建实例,同时触发Name属性的验证 .ConstructUsing(src => new Car(src.Name)) // 手动设置Description,触发模型本身的验证逻辑 .AfterMap((src, dest) => dest.Description = src.Description) .ReverseMap(); } }
原理说明
- ConstructUsing:指定AutoMapper使用Car的带参构造函数创建实例,此时Name属性的setter会执行验证,如果Name不符合长度要求,会直接抛出
ArgumentOutOfRangeException。 - AfterMap:在实例创建完成后,手动给Description赋值,这一步完全由Car模型的setter逻辑处理,抛出的异常不会被AutoMapper捕获包装,直接传递给调用方。
这样修改后,单元测试就能捕获到Car模型抛出的ArgumentOutOfRangeException,符合预期。
备选方案:全局禁用AutoMapper异常包装
如果希望所有映射都直接抛出原始异常,可以全局配置AutoMapper,但这种方式会影响所有映射场景,建议谨慎使用:
var mapperConfig = new MapperConfiguration(cfg => { cfg.AddProfile<CarProfile>(); // 全局配置,让属性赋值时的原始异常直接抛出 cfg.ForAllMaps((map, expr) => { expr.ForAllMembers(opt => opt.SetResolveUsing((src, dest, context) => { var value = opt.ResolveValue(src, context); opt.DestinationMember.SetValue(dest, value); return value; })); }); });
内容的提问来源于stack exchange,提问作者Mehran Kordavani
相关产品推荐
相关产品推荐

