如何使用AutoMapper将SetEmr DTO映射为Dictionary<string, object>?
问题描述
尝试使用AutoMapper将DTO SetEmr 映射为 Dictionary<string, object>,DTO定义如下:
public class SetEmr { public string Name { get; set; } public int Repeat { get; set; } public int RestTime { get; set; } public int Order { get; set; } }
编写的映射配置如下:
CreateMap<SetEmr, Dictionary<string, object>>() .ForMember(dest => dest, opt => opt.MapFrom((src, dst, _, context) => { return new Dictionary<string, object> { { "Name", src.Name }, { "Repeat", src.Repeat}, { "Order", src.Order} }; }));
运行时报错:
"Custom configuration for members is only supported for top-level individual members on a type."
需要实现该映射的其他方法。
可行解决方案
方法1:使用ConvertUsing直接定义转换逻辑
ForMember仅用于配置目标类型的单个成员,而这里目标是整个字典,应使用ConvertUsing直接指定类型间的转换逻辑:
CreateMap<SetEmr, Dictionary<string, object>>() .ConvertUsing(src => new Dictionary<string, object> { { nameof(SetEmr.Name), src.Name }, { nameof(SetEmr.Repeat), src.Repeat }, { nameof(SetEmr.Order), src.Order } });
该方式直接绕过ForMember的限制,明确生成包含指定键值对的字典。
方法2:利用AutoMapper自动扁平化映射
如果需要映射所有属性,无需手动编写键值对,AutoMapper支持自动将对象属性转换为字典:
CreateMap<SetEmr, Dictionary<string, object>>();
调用mapper.Map<Dictionary<string, object>>(setEmr)后,会自动生成包含Name、Repeat、RestTime、Order四个键的字典。若需排除特定属性(比如RestTime),可搭配ForMember忽略:
CreateMap<SetEmr, Dictionary<string, object>>() .ForMember("RestTime", opt => opt.Ignore());
方法3:自定义类型转换器(适合复杂逻辑复用)
如果转换逻辑需要复用或更复杂,可创建实现ITypeConverter的转换器类:
public class SetEmrToDictionaryConverter : ITypeConverter<SetEmr, Dictionary<string, object>> { public Dictionary<string, object> Convert(SetEmr source, Dictionary<string, object> destination, ResolutionContext context) { return new Dictionary<string, object> { { nameof(SetEmr.Name), source.Name }, { nameof(SetEmr.Repeat), source.Repeat }, { nameof(SetEmr.Order), source.Order } }; } }
然后在映射配置中注册该转换器:
CreateMap<SetEmr, Dictionary<string, object>>() .ConvertUsing<SetEmrToDictionaryConverter>();
内容的提问来源于stack exchange,提问作者Mikhail Kostiuchenko
相关产品推荐
相关产品推荐

