asp.net AddJsonOptions在Blazor服务器中不起作用

gr8qqesn  于 2023-01-22  发布在  .NET
关注(0)|答案(1)|浏览(174)

我想添加全局JsonSerializer选项来使用ReferenceHandler.Preserve,但我无法配置我的blazor服务器应用程序来将其用作所有json Serializer的全局设置。
我以前

builder.Services.ConfigureHttpJsonOptions(options =>
    {
        options.SerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
        options.SerializerOptions.PropertyNameCaseInsensitive = true;
    });

builder.Services.AddRazorPages().AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    });

builder.Services.Configure<JsonOptions>(o =>
   {
       o.SerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
       o.SerializerOptions.PropertyNameCaseInsensitive = true;
   });

没有一个像预期的那样工作,选项没有从默认值更改,我一直得到相同的异常:"JSON值无法转换为"在每个请求中使用相同的选项

var options = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve, PropertyNameCaseInsensitive = true };
var httpClient = _httpFactory.CreateClient("API");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _tokenProvider.JwtToken);
var result = await httpClient.GetFromJsonAsync<List<Manufacturer>>("manufacturer", options);

但是我想定义所有请求的选项,而不是每次都显式地写入它们。

kcrjzv8t

kcrjzv8t1#

您可以使用Typed Client(甚至使用NSwagRefit生成)来代替Named Client,并在此类型化API客户机中处理JSON选项。
例如,NSwag API客户端生成器具有an option to generateUpdateJsonSerializerSettings方法,您可以在dAPI客户端类型的基类中定义该方法,如下所示:

internal class BaseClient
{
    protected static void UpdateJsonSerializerSettings(JsonSerializerOptions settings) => settings.ConfigureDefaults();
}

// generated API client: 
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.16.1.0 (NJsonSchema v10.7.2.0 (Newtonsoft.Json v13.0.0.0))")]
internal partial class SomeClient : BaseClient, ISomeClient
{
    private System.Net.Http.HttpClient _httpClient;
    private System.Lazy<System.Text.Json.JsonSerializerOptions> _settings;

    public ActionsClient(System.Net.Http.HttpClient httpClient)
    {
        _httpClient = httpClient;
        _settings = new System.Lazy<System.Text.Json.JsonSerializerOptions>(CreateSerializerSettings);
    }

    private System.Text.Json.JsonSerializerOptions CreateSerializerSettings()
    {
        var settings = new System.Text.Json.JsonSerializerOptions();
        UpdateJsonSerializerSettings(settings);
        return settings;
    }
    ... the rest of generated code has omitted 
}

// Extension which configures the default JSON settings (as an example): 
public static class JsonExtensions
{
    private static JsonSerializerOptions GetDefaultOptions() => new() { WriteIndented = true };

    public static JsonSerializerOptions ConfigureDefaults(this JsonSerializerOptions? settings)
    {
        settings ??= GetDefaultOptions();

        settings.PropertyNameCaseInsensitive = true;
        settings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        settings.NumberHandling = JsonNumberHandling.AllowReadingFromString;
        settings.Converters.Add(new JsonStringEnumConverter());

        return settings;
    }
}

然后在DI上注册ISomeClient类型的客户端,如下所示:

builder.Services
    .AddScoped<MyLovelyAuthorizationMessageHandler>()
    .AddHttpClient<ISomeClient, SomeClient>(httpClient => 
    {
        httpClient.BaseAddress = new Uri(apiSettings.WebApiBaseAddress);
        // ...etc.
    }).AddHttpMessageHandler<MyLovelyAuthorizationMessageHandler>();

然后,在需要的地方注入ISomeClient,并使用类型化的DTOs调用方法,将所有JSON序列化/反序列化魔法隐藏起来。

[Inject] private ISomeClient Client {get; set;} = default!;

文件:关于类型化客户端

相关问题