使用AutoMapper将API字符串TryParse为枚举失败,求解决方案
解决AutoMapper字符串转Enum解析失败抛出异常的问题
问题场景
需求:通过AutoMapper将API传入的字符串类型类别转换为Enum类型,解析失败时返回默认值Category.Others。
相关代码定义:
枚举Category
public enum Category : int { Others = 0, Food = 1, Health = 2, Home = 3, Transport = 4, Education = 5, Chill = 6, Unexpected = 7 }
实体类与DTO
- Expense类:包含
Id、Description、Value、Date、Category类型的Category属性(注:原描述中笔误为Categories,以映射代码为准) - ExpenseDTO类:包含对应属性,其中
Categories为string类型
尝试的映射配置(存在问题)
CreateMap<ExpenseDTO, Expense>() .ForMember(dest => dest.Category, opt => { object? parsedResult; opt.MapFrom(src => Enum.TryParse(typeof(Category), src.Categories, true, out parsedResult) ? parsedResult : Category.Others); }) .ReverseMap().ForMember(dest => dest.Category, opt => opt.MapFrom(src => src.Categories.ToString()));
报错信息
当传入不存在的类别(如"Test")时,抛出映射异常:
Mapping types: ExpenseDTO -> Expense Challenge.API.ExpenseDTO -> Challenge.Domain.Expense Type Map configuration: ExpenseDTO -> Expense Challenge.API.ExpenseDTO -> Challenge.Domain.Expense
问题原因
- 使用非泛型
Enum.TryParse返回object类型,AutoMapper无法正确推断目标类型,导致类型转换异常。 - ReverseMap阶段属性名错误:DTO的目标属性应为
Categories,而非Category,存在属性不匹配问题。 - 未显式处理
src.Categories为null的场景,可能引发额外转换问题。
解决方案
使用泛型版本的Enum.TryParse<Category>确保类型强匹配,修正ReverseMap的属性名,同时处理null场景:
CreateMap<ExpenseDTO, Expense>() // 正向映射:字符串转Enum,失败返回默认值 .ForMember(dest => dest.Category, opt => opt.MapFrom(src => Enum.TryParse(src.Categories, ignoreCase: true, out Category parsedCategory) ? parsedCategory : Category.Others)) // 反向映射:Enum转字符串 .ReverseMap() .ForMember(dest => dest.Categories, opt => opt.MapFrom(src => src.Category.ToString()));
关键改进点
- 泛型
Enum.TryParse<Category>直接返回强类型结果,避免object到Category的隐式转换问题,AutoMapper可正确识别映射类型。 - 自动处理
src.Categories为null的情况(此时TryParse返回false,直接返回默认值)。 - 修正ReverseMap的目标属性为
dest.Categories,与DTO的属性名匹配,避免属性不存在的错误。
内容的提问来源于stack exchange,提问作者Victor Teixeira
相关产品推荐
相关产品推荐

