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

AutoMapper从7版本升级到10版本后的对象映射问题解决

问题描述

以下是在LinqPad 5(.Net Framework)中编写的代码示例:

void Main()
{
    var o = new A() { b = new B() { Msj = "Hello, world!" } };
    var r = MapObject<C, A>(o);
    r.Dump();
}

public class A
{
    public B b {get;set;}
}

public class B
{
    public string Msj {get;set;}
}

public class C
{
    public D b { get; set; }
}

public class D
{
    public string Msj { get; set; }
}


private static Tdst MapObject<Tdst, Tori>(Tori obj)
{
    var configMapper = new AutoMapper.MapperConfiguration(cfg => cfg.CreateMap<Tori, Tdst>());
    var mapper = configMapper.CreateMapper();
    return mapper.Map<Tdst>(obj);
}

这段代码在AutoMapper 7版本中运行正常,但升级到10版本后,抛出如下错误:

AutoMapperMappingException: Error mapping types.

Mapping types:
A -> C
UserQuery+A -> UserQuery+C

Type Map configuration:
A -> C
UserQuery+A -> UserQuery+C

Destination Member:
b

已知类A和C结构完全一致,但来自不同Web服务(不同命名空间),需要修改MapObject方法,使其在AutoMapper 10中正常工作。

注:已通过Mapster解决该问题,好奇AutoMapper的解决方案。

解决方案

AutoMapper从8.x版本开始,默认不再自动映射嵌套类型,必须显式配置嵌套类型的映射规则。以下是两种修改方案:

方案1:针对单个嵌套属性配置

如果只需要处理示例中的b属性,可直接显式添加嵌套类型的映射:

private static Tdst MapObject<Tdst, Tori>(Tori obj)
{
    var configMapper = new AutoMapper.MapperConfiguration(cfg => 
    {
        cfg.CreateMap<Tori, Tdst>();
        // 显式添加嵌套类型B到D的映射
        cfg.CreateMap<B, D>();
    });
    var mapper = configMapper.CreateMapper();
    return mapper.Map<Tdst>(obj);
}

方案2:通用嵌套类型自动配置

如果需要支持任意同名同结构的嵌套属性,可通过反射自动遍历并添加映射规则:

private static Tdst MapObject<Tdst, Tori>(Tori obj)
{
    var configMapper = new AutoMapper.MapperConfiguration(cfg => 
    {
        cfg.CreateMap<Tori, Tdst>();
        
        // 遍历源类型和目标类型的所有属性
        var sourceProps = typeof(Tori).GetProperties();
        var destProps = typeof(Tdst).GetProperties();
        
        foreach (var srcProp in sourceProps)
        {
            var destProp = destProps.FirstOrDefault(p => p.Name == srcProp.Name);
            // 仅处理引用类型(排除值类型和字符串)的同名属性
            if (destProp != null && !srcProp.PropertyType.IsValueType && srcProp.PropertyType != typeof(string))
            {
                cfg.CreateMap(srcProp.PropertyType, destProp.PropertyType);
            }
        }
    });
    var mapper = configMapper.CreateMapper();
    return mapper.Map<Tdst>(obj);
}

原因说明

AutoMapper 7及更早版本会自动尝试映射同名的嵌套类型,即使它们属于不同命名空间。但从8.x版本开始,为了提升性能、减少意外映射的风险,官方默认关闭了这一自动行为,要求开发者显式声明所有需要映射的类型对。

内容的提问来源于stack exchange,提问作者rasputino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:05:20