ASP.NET Core Razor Pages全局配置STJ枚举反序列化失败问题
解决ASP.NET Core 8 Razor Pages中HttpClient全局反序列化枚举为字符串的问题
问题原因
你之前配置的MvcJsonOptions仅作用于MVC/Razor Pages的模型绑定、Action返回结果序列化场景,和HttpClient的GetFromJsonAsync等Json扩展方法无关;而ConfigureHttpJsonOptions需要配合DI管理的HttpClient才能生效,直接使用未配置的HttpClient不会读取这些全局设置。
正确解决方案
方案1:通过IHttpClientFactory配置带全局Json选项的HttpClient
在Program.cs中注册HttpClient时,直接配置其对应的Json序列化选项:
using System.Text.Json; using System.Text.Json.Serialization; // 注册带配置的HttpClient builder.Services.AddHttpClient("DownstreamApiClient") .ConfigureHttpClient(client => { // 设置下游API的基础地址(可选) client.BaseAddress = new Uri("https://your-downstream-api-base-url/"); }) .ConfigureHttpJsonOptions(options => { options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; });
然后在Razor Page模型中注入IHttpClientFactory,使用配置好的客户端发起请求:
public class YourPageModel : PageModel { private readonly IHttpClientFactory _httpClientFactory; public YourPageModel(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task OnGetAsync(CancellationToken cancellationToken) { var httpClient = _httpClientFactory.CreateClient("DownstreamApiClient"); var objectWithEnumProperty = await httpClient.GetFromJsonAsync<ObjectWithEnumProperty>("some/uri", cancellationToken); // 后续逻辑 } }
方案2:全局配置HttpJsonOptions(作用于所有DI管理的HttpClient)
如果希望所有通过DI获取的HttpClient都使用统一的Json配置,可以直接全局配置HttpJsonOptions:
using System.Text.Json; using System.Text.Json.Serialization; builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; }); // 注册基础HttpClient(无需额外配置Json选项) builder.Services.AddHttpClient();
之后在Razor Page中直接注入HttpClient即可使用全局配置:
public class YourPageModel : PageModel { private readonly HttpClient _httpClient; public YourPageModel(HttpClient httpClient) { _httpClient = httpClient; } public async Task OnGetAsync(CancellationToken cancellationToken) { var objectWithEnumProperty = await _httpClient.GetFromJsonAsync<ObjectWithEnumProperty>("https://your-downstream-api.com/some/uri", cancellationToken); // 后续逻辑 } }
注意事项
- 避免直接
new HttpClient,因为这样的实例不会读取DI中配置的任何选项,同时还会导致连接池耗尽等问题。 - 如果必须使用默认的
JsonSerializerOptions.Default(不推荐,会影响全局所有Json操作),可以直接修改全局默认选项:JsonSerializerOptions.Default.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; JsonSerializerOptions.Default.Converters.Add(new JsonStringEnumConverter()); JsonSerializerOptions.Default.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
内容的提问来源于stack exchange,提问作者Kralizek
相关产品推荐
相关产品推荐

