【问题标题】:How can I set a global JSON options for ReadFromJsonAsync method?如何为 ReadFromJsonAsync 方法设置全局 JSON 选项?
【发布时间】:2022-06-13 15:32:45
【问题描述】:

我有一个使用 .net core 6 的 Web 应用项目,我正在尝试从我构建的另一个 API 中获取一些 JSON 数据。在该 API 中,我返回的 JSON 包含一些转换为字符串的枚举。然后在我的网络应用程序项目中,ReadFromJsonAsync 方法会抛出异常,因为它无法将这些字符串转换回枚举或其他东西,所以我可以通过为ReadFromJsonAsync 方法设置 JSON 选项来修复它,如下所示:

public class AuthService : IAuthService
{
    private readonly HttpClient _client;

    public AuthService(HttpClient client)
    {
        _client = client;
    }

    public async Task<ApiResult<LoginResponse>?> Login(LoginCommand command)
    {
        var result = await _client.PostAsJsonAsync("api/auth/login", command);
    
        var options = new JsonSerializerOptions
        {
            Converters = {new JsonStringEnumConverter()},
            PropertyNameCaseInsensitive = true
        };
        var content = await result.Content.ReadFromJsonAsync<ApiResult<LoginResponse>>(options);

        return content;
    }
}

这可行,但问题是我将在不同的类中大量使用此方法,我不能每次都编写这些选项,所以我想全局应用这些选项。

我尝试在我的 Program.cs 课程中这样做,但它根本不起作用:

builder.Services.AddRazorPages().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});

如何在全局范围内应用这些选项?这样我就不必每次都通过这些选项?

【问题讨论】:

  • 您可以将IOptions&lt;JsonOptions&gt; 注入到控制器或操作方法中(然后使用options.Value.JsonSerializerOptions)。除了基本的HttpClient 之外,您在此处配置的选项和依赖注入都已脱离循环。如果有一些运动可以改善这一点,那就太好了。
  • @DiplomacyNotWar 抱歉,我不明白你所说的外循环是什么意思?什么是循环之外的,应该改进什么?对不起,我的英语不是很好,我可能误解了你的意思。我应该如何在我的Program.cs 类中注入IOptions&lt;JsonOptions&gt;?我将它添加到我的类的构造函数中,但我不知道如何在我的 Program.cs 中注册该依赖项
  • 如果有一种方法可以全局应用这些选项,并且不必将任何options 参数传递给ReadFromJsonAsync 方法,那将是理想的。 idk 如果可能的话。
  • 我的意思是ReadFromJsonAsyncHttpContent 的扩展方法。因此,没有依赖注入。

标签: c# asp.net-core asp.net-web-api razor razor-pages


【解决方案1】:

目前,我像这样直接注入它,但我仍然想知道是否有一种方法可以全局应用这些选项,甚至无需将 options 参数传递给 ReadFromJsonAsync 方法。

在我的program.cs 班级:

builder.Services.AddSingleton(new JsonSerializerOptions
{
    Converters = { new JsonStringEnumConverter() },
    PropertyNameCaseInsensitive = true
});

我是这样使用它的:

public class AuthService : IAuthService
{
    private readonly HttpClient _client;
    private readonly JsonSerializerOptions _jsonOptions;

    public AuthService(HttpClient client, JsonSerializerOptions jsonOptions)
    {
        _client = client;
        _jsonOptions = jsonOptions;
    }

    public async Task<ApiResult<LoginResponse>?> Login(LoginCommand command)
    {
        var result = await _client.PostAsJsonAsync("api/auth/login", command);
        var content = await result.Content.ReadFromJsonAsync<ApiResult<LoginResponse>>(_jsonOptions);
        return content;
    }
}

【讨论】:

  • 您不需要像这样单独注册设置。 AddJsonOptions 已经在注册 IOptions&lt;JsonOptions&gt; 。你可以注入它。
  • 我试过你说的,但它不起作用,由于某种原因,AddJsonOptions 根本不起作用,当我在AddRazorPages 之后添加它时,就像这样:AddRazorPages().AddJsonOptions(options =&gt; ...) 然后我将IOptions&lt;JsonOptions&gt; 注入我的班级,但没有任何效果。
  • 你的意思是IOptions&lt;JsonOptions&gt;没有被注入?
  • 看起来是这样,但是如果我启动我的项目,它不会因为无法解决该依赖关系而引发异常,它会引发关于我返回的 API 结果的异常,它可以' t 将字符串转换回枚举,此异常:JsonException: The JSON value could not be converted to Common.Api.ApiStatusCode ApiStatusCode 是导致问题的枚举。
  • 您是否将JsonSerializerOptions 值从IOptions&lt;JsonOptions&gt; 传递到ReadFromJsonAsync?听起来你没有。
猜你喜欢
  • 2020-02-08
  • 2017-06-16
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2014-10-05
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
相关资源
最近更新 更多