.NET 7 + AutoMapper 11.0.1泛型约束异常问题求助
完整代码
// See https://aka.ms/new-console-template for more information using AutoMapper; Console.WriteLine("Hello, World!"); var mapperConfig = new MapperConfiguration(mc => { mc.AddProfile(new MappingProfile()); }); //mapperConfig.AssertConfigurationIsValid(); IMapper mapper = mapperConfig.CreateMapper(); var entity = new Entity() { Created = DateTime.Now }; var entityDto = mapper.Map<Entity, EntityDto>(entity); Console.WriteLine("Test"); public class MappingProfile : Profile { public MappingProfile() { CreateMap<Entity, EntityDto>().ReverseMap(); } } public class Entity { public Guid Guid { get; set; } public DateTime Created { get; set; } public string CreatedById { get; set; } public ApplicationUser CreatedBy { get; set; } } public class EntityDto { public Guid Guid { get; set; } public DateTime Created { get; set; } public string CreatedById { get; set; } } public class ApplicationUser { }
问题现象
移除Entity类中的public ApplicationUser CreatedBy { get; set; }或EntityDto类中的public DateTime Created { get; set; }后,代码可正常运行。
版本限制
该问题仅出现在**.NET 7 + AutoMapper 11.0.1环境中,使用.NET 7 + AutoMapper 12.0.0或.NET 6 + AutoMapper 11.0.1**时无异常。由于项目依赖Microsoft.AspNetCore.ApiAuthorization.IdentityServer/7.0.0,其依赖的Duende.IdentityServer.EntityFramework.Storage/6.0.4限制AutoMapper版本范围为>=11.0.0 && <12.0.0,无法直接升级至AutoMapper 12.0.0;手动升级Duende.Identity相关NuGet包会导致Microsoft.AspNetCore.ApiAuthorization.IdentityServer出现兼容性问题,因此该方案不可行。
异常信息
System.ArgumentException: 'GenericArguments[0], 'System.DateTime', on 'T MaxInteger[T](System.Collections.Generic.IEnumerable`1[T])' violates the constraint of type 'T'.' Inner Exception VerificationException: Method System.Linq.Enumerable.MaxInteger: type argument 'System.DateTime' violates the constraint of type parameter 'T'.
解决方案
这是AutoMapper 11.x在.NET7环境下的兼容性bug,当映射包含DateTime字段和未映射的导航属性(如Entity中的CreatedBy)时,会触发内部错误。以下是无需修改实体/DTO核心字段、不升级AutoMapper的解决方法:
方法1:显式配置映射规则并忽略未使用的导航属性
修改MappingProfile,明确指定核心字段映射规则,并在反向映射时忽略CreatedBy导航属性,避免AutoMapper自动处理该字段引发错误:
public class MappingProfile : Profile { public MappingProfile() { CreateMap<Entity, EntityDto>() .ForMember(dest => dest.Guid, opt => opt.MapFrom(src => src.Guid)) .ForMember(dest => dest.Created, opt => opt.MapFrom(src => src.Created)) .ForMember(dest => dest.CreatedById, opt => opt.MapFrom(src => src.CreatedById)) .ReverseMap() .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()); } }
方法2:全局禁用构造函数自动映射
如果多个映射存在类似问题,可在MapperConfiguration中全局禁用构造函数自动映射,避免AutoMapper尝试通过构造函数处理未预期的类型:
var mapperConfig = new MapperConfiguration(mc => { mc.AddProfile(new MappingProfile()); mc.DisableConstructorMapping(); });
方法3:启用映射配置验证(辅助排查)
取消注释mapperConfig.AssertConfigurationIsValid();,启动时验证映射配置完整性,快速定位未正确配置的字段,确保所有预期映射都被显式定义。
内容的提问来源于stack exchange,提问作者Ogglas

