使用AutoMapper进行元组映射时遇到的异常问题
AutoMapper元组映射异常解决
源/目标类型
// 源类型 public record AuthorRequest( string Name, string Biography, DateTime DateOfBirth); // 目标类型 public record AuthorUpdateCommand( Guid Id, string Name, string Biography, DateTime DateOfBirth ) : AuthorCommand(Name, Biography, DateOfBirth), IRequest<Result<Updated>>;
映射配置(原错误写法)
public class AuthorProfile : Profile { public AuthorProfile() { CreateMap<(Guid Id, AuthorRequest AuthorRequest), AuthorUpdateCommand>() .ForMember(dst => dst, opt => opt.MapFrom(src => src.AuthorRequest)) .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id)); } }
使用版本
AutoMapper 13.0.1
预期行为
希望实现类似Mapster的元组投影功能,将包含Id和AuthorRequest的元组转换为AuthorUpdateCommand,且后续新增字段时无需修改映射配置。
实际行为
运行时抛出异常:
已发生异常: CLR/System.ArgumentException 在AutoMapper.dll中发生类型为'System.ArgumentException'的异常,但未在用户代码中处理: '表达式'dst => dst'必须解析为顶级成员,而非子对象的属性。可改用ForPath、子类型的自定义解析器或AfterMap选项。' 在 AutoMapper.Internal.ReflectionHelper.FindProperty(LambdaExpression lambdaExpression) 在 AutoMapper.Configuration.MappingExpression`2.ForMember[TMember](Expression`1 destinationMember, Action`1 memberOptions) 在 CatalogContext.Application.Common.Mappings.AuthorProfile..ctor() 位置 c:\Users\jose\Music\github\Projetos\BookVerse\CatalogContext\src\CatalogContext.Application\Common\Mappings\AuthorProfile.cs:第16行 在 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
复现步骤
控制器中传递元组执行映射时触发异常:
public record AuthorRequest( string Name, string Biography, DateTime DateOfBirth); [HttpPut("{id:guid}")] public async Task<IActionResult> Update(Guid id, AuthorRequest request) { var command = _mapper.Map<AuthorUpdateCommand>((id, request)); var result = await _mediator.Send(command); if (result.IsError) { return BadRequest(); } return Ok(result.Value); }
解决方案
异常原因
原配置中ForMember(dst => dst)的写法违反AutoMapper规则:ForMember方法仅支持指定目标类型的单个顶级属性,不能直接映射整个目标对象,因此触发参数异常。
正确映射配置
使用IncludeMembers方法让AutoMapper自动复用AuthorRequest到AuthorUpdateCommand的同名属性映射,仅需单独配置Id字段:
public class AuthorProfile : Profile { public AuthorProfile() { CreateMap<(Guid Id, AuthorRequest AuthorRequest), AuthorUpdateCommand>() .IncludeMembers(src => src.AuthorRequest) // 自动映射AuthorRequest中的所有同名属性 .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id)); } }
效果说明
IncludeMembers会将元组中的AuthorRequest对象纳入映射数据源,自动匹配Name、Biography、DateOfBirth等同名字段。- 后续若给
AuthorRequest和AuthorUpdateCommand新增同名字段,无需修改映射配置,AutoMapper会自动处理,完全符合需求。
内容的提问来源于stack exchange,提问作者Jose Santo
相关产品推荐
相关产品推荐

