ASP.NET Core Web API:条件序列化

问题描述 投票:0回答:1

我有一个用户群,他们有不同的主张来代表他们的计划。我想根据对象的计划从对象中删除一些字段。

我在这里找到了答案:ASP.NET WebAPI Conditional Serialization based on User Role

但它仅适用于

HttpClient
,因为我无法在 ASP.NET Core 8 中使用
DelegatingHandler
(或者不明白如何使用) - 有没有类似的方法来操纵我所有控制器的响应?

c# asp.net-core-webapi .net-8.0
1个回答
0
投票

为此我只能想到编写自定义

JsonConverter
。我会给你步骤+初步实施。更多细节您需要弄清楚。

那么,让我们从实现示例

JsonConverter
开始。由于您想隐藏某些字段,我假设您知道类型,并且根据用户知道要隐藏什么和不隐藏什么。为了简单起见,我实现了“对未经身份验证的用户不返回任何内容”:

public class JsonHideConverter<T> : JsonConverter<T>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public JsonHideConverter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        // For other types than specified,
        // do not do nothing, just return full info.
        if (typeof(T) != typeof(WeatherForecast))
        {
            JsonSerializer.Serialize(writer, value);
            return;
        }

        // If user is authenticated, return full info.
        if (_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
        {
            JsonSerializer.Serialize(writer, value);
            return;
        }

        // Hide all together for unauthenticated user.
        return;
    }
}

一切都很好,但是将

IHttpContextAccessor
放入转换器非常棘手。为此,我们必须实现另一个接口
IConfigureOptions<JsonOptions>
(来自
JsonOptions
命名空间的
Microsoft.AspNetCore.Mvc
):

public class ConfigOptions : IConfigureOptions<JsonOptions>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ConfigOptions(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Configure(JsonOptions options)
    {
        options.JsonSerializerOptions.Converters.Add(new JsonHideConverter<WeatherForecast>(_httpContextAccessor));
    }
}

最后,我们需要将

ConfigOptions
注册为单例,但它需要
IHttpContextAccessor
,默认情况下是作用域服务,但将其注册为单例是完全可以的:

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<IConfigureOptions<JsonOptions>, ConfigOptions>();

有了这一切,您就可以开始使用我们的转换器,并根据所编写的响应类型和手头的用户信息进行自定义检查来增强它。

希望有帮助。

参考资料:

© www.soinside.com 2019 - 2024. All rights reserved.