You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
    }
}

原理说明

  1. ConstructUsing:指定AutoMapper使用Car的带参构造函数创建实例,此时Name属性的setter会执行验证,如果Name不符合长度要求,会直接抛出ArgumentOutOfRangeException。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:31:58