我有一个用.NET6开发的API.目前,所有返回为空的属性都通过以下方式隐藏:

_ = services.AddControllers().AddJsonOptions(options => {
    options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; });

我还需要忽略空字符串的值.在那里,我实现了以下转换器:

public class EmptyStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return reader.GetString()!;
    }
    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        if (!string.IsNullOrEmpty(value))
        {
            writer.WriteStringValue(value);
        }
        else
        {
            writer.WriteNullValue();
        }
    }
}

将转换器添加到AddJsonOptions:

_ = services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new EmptyStringConverter());
    options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});

转换器正在工作-将空字符串属性更改为NULL,但在API响应中,这些属性是可见的,尽管我已经设置了

  DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull.

我查看了其他文章,指出要添加默认属性,但这意味着必须更改所有模型的所有属性,这是不可行的.此外,这也意味着值为0的数字将被隐藏,这不是我想要的.

我需要使用System.Text.Json而不是Newtonsoft.

请问有什么办法可以做到这一点吗?

推荐答案

可以由DefaultJsonTypeInfoResolver或派生类型使用customize the JSON contract.

下面的代码将每个类型为string的属性更改为仅在非Null和非空时序列化.

这种通过属性类型判断进行的合同定制对于每个模型类型只发生一次.对于每个string属性值运行的是应用于ShouldSerializeFunc.

builder.Services
    .AddControllers()
    .AddJsonOptions(o => o.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver()    
    {
        Modifiers =
        { 
            jsonTypeInfo => 
            {
                foreach (var propertyInfo in jsonTypeInfo.Properties.Where(o => o.PropertyType == typeof(string)))
                {
                    propertyInfo.ShouldSerialize = (parent, property) => !string.IsNullOrEmpty(property as string);
                }
            }
        }
    });

Csharp相关问答推荐

在包含空项的列表上使用具有断言T的摘要表

FromServices不使用WebAppliationFactory程序>

以自动方式注销Azure身份应用程序

如何使用CsvReader获取给定列索引的列标题?

Polly使用泛型重试和重试包装函数

使页面内容居中

System.Net.Http.HttpClient.SendAsync(request)在docker容器内的POST方法30秒后停止

HttpClient 415不支持的媒体类型错误

取决于您的数据量的多个嵌套循环

DbContext-传递自定义配置选项

如何在GRPC代码First服务的返回类型上使用多态性?

在集成测试中可以在模拟InMemory数据库中设定数据种子

System.NotSupportdException:流不支持读取

如何在Polly重试策略成功之前将HttpClient请求排队?

为什么在使用JsonDerivedType序列化泛型时缺少$type?

NETSDK1201:对于面向.NET 8.0和更高版本的项目,默认情况下,指定RUNTIME标识符将不再生成自包含的应用程序

Xamarin Forms应用程序中登录页面的用户名和密码编辑文本之间不需要的空格

.NET6最小API:操作.MapGet之后的响应

带有类约束的C#泛型

C#:我需要根据换行符拆分字符串,而不是在字符串中用双引号分隔换行符