.NET 9中GetFromJsonAsync枚举JSON转换JsonException异常问题
问题解决:.NET 9 HttpClient GetFromJsonAsync 枚举反序列化失败且自定义配置后数据为空
核心问题分析
控制器中配置的JsonStringEnumConverter仅作用于接口输出的JSON序列化,而HttpClient.GetFromJsonAsync使用的是独立的序列化配置,两者不共享。你自定义JsonSerializerOptions后数据全空,大概率是因为没有保留默认的属性匹配规则(比如驼峰命名映射、大小写不敏感匹配),导致JSON属性和实体类属性无法对应。
解决方案
1. 创建正确的全局序列化配置
在Program.cs中注册一个包含枚举转换器且继承Web默认规则的JsonSerializerOptions实例,确保属性匹配和枚举转换都正常:
builder.Services.AddSingleton<JsonSerializerOptions>(_ => { // 继承.NET Web场景的默认配置:驼峰命名、属性大小写不敏感等 var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); // 添加枚举字符串转换器,指定命名策略(根据你的JSON枚举值格式调整) options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); return options; });
2. 在HttpClient调用时复用该配置
通过依赖注入获取配置,传入GetFromJsonAsync:
public class PersonService { private readonly HttpClient _httpClient; private readonly JsonSerializerOptions _jsonOptions; public PersonService(HttpClient httpClient, JsonSerializerOptions jsonOptions) { _httpClient = httpClient; _jsonOptions = jsonOptions; } public async Task<List<PersonWithGender>> FetchPersons() { return await _httpClient.GetFromJsonAsync<List<PersonWithGender>>("your-api-endpoint", _jsonOptions); } }
3. 调整枚举转换器的命名策略(按需)
如果你的JSON中枚举值是帕斯卡命名(比如"Male")而非驼峰("male"),修改转换器的命名策略:
// 匹配帕斯卡命名的枚举值 options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.PascalCase)); // 或者完全不做大小写转换,严格匹配枚举名称 options.Converters.Add(new JsonStringEnumConverter(null));
为什么之前的自定义配置会导致数据为空?
直接new JsonSerializerOptions()会创建一个无默认规则的实例,默认情况下:
PropertyNameCaseInsensitive为false,JSON属性名和实体类属性名必须完全一致(比如JSON是"firstName",实体是FirstName就匹配失败)- 没有设置
PropertyNamingPolicy,无法自动映射驼峰和帕斯卡命名
使用JsonSerializerDefaults.Web继承了Web场景的最优配置,解决了属性匹配问题,同时添加枚举转换器解决反序列化失败的问题。
内容的提问来源于stack exchange,提问作者MrChudz
相关产品推荐
相关产品推荐

