使用新的 Net Core 3.0 Json 时忽略属性

Posted

技术标签:

【中文标题】使用新的 Net Core 3.0 Json 时忽略属性【英文标题】:Ignore property when null using the new Net Core 3.0 Json 【发布时间】:2019-09-25 21:08:30 【问题描述】:

在 ASP.Net Core 2.2 中使用 JSON.Net 时,我能够在序列化为 JSON 时忽略其值为 null 的属性:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public DateTime? Created  get; set; 

但是,当使用 JSON (System.Text.Json) 中内置的新 ASP.Net Core 3.0 时,如果属性值为 null,我找不到等效属性来忽略属性。

我只能找到 JsonIgnore。

我错过了什么吗?

【问题讨论】:

corefx github 上有一个线程建议实现这一点,但目前使用JsonSerializerOptions.IgnoreNullValues 似乎是一个全有或全无的事情 System.Text.Json 目前适用于简单的场景。它的主要重点是速度和低分配。您可能必须使用自定义格式化程序或在更高级的场景中使用 JSON.NET @PanagiotisKanavos 你在说 JsonConverter 吗?我一直在寻找如何做到这一点的例子,但我找不到任何...... @SimplyGed 知道现在如何使用 System.Text.Json 来完成此任务,即使需要额外的代码? 这能回答你的问题吗? .NET Core: Remove null fields from API JSON response 【参考方案1】:

我正在查看 .Net Core 3.1,它应该忽略空值

    services.AddControllers().AddJsonOptions(options =>
    
        options.JsonSerializerOptions.IgnoreNullValues = true;
    );

请注意,以上内容并非针对每个属性/属性,尽管有一个属性可能会有所帮助JsonIgnoreAttribute

解决您的问题的替代方法可能是JsonConverterAttribute,有关如何编写自己的转换器的信息是here

【讨论】:

现在是options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull【参考方案2】:

这已在 .Net 5 上修复

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

查看下面的更新

https://github.com/dotnet/runtime/issues/41313

https://github.com/dotnet/runtime/issues/30687

【讨论】:

【参考方案3】:

如果您希望在 JSON 序列化期间忽略空值的属性级别控制,对于 Net Core 3.1,您必须编写一个自定义转换器。 Newtonsoft.Json migration documentation中有examples described。

这对于使用 Newtonsoft.Json 声明性的功能来说是一个很大的麻烦。您可以通过specifying as much in Startup.ConfigureServices()指定使用Newtonsoft.Json。

services.AddControllers()
    .AddNewtonsoftJson();

如文档所述,您需要添加 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包。

【讨论】:

这个答案很可能是每个人都在追求的答案。由于 IgnoreNullValues 似乎仅适用于条目对象的反序列化。如果你和我一样,想要保持相同的请求和响应合同,添加 newtonsoft 是唯一的选择。例如,我返回的对象会省略任何可以为空的字段,不幸的是这会破坏我们拥有的“非官方”合同。【参考方案4】:

将它添加到您的初创公司应该会有所帮助,尽管它不是每个属性,也不是一个属性。

services.AddMvc()
        .AddJsonOptions(options => options.JsonSerializerOptions.IgnoreNullValues = true; );

【讨论】:

【参考方案5】:

如果您仍在 .net core 3.1 中使用 Newtonsoft.Json,您希望进行如下配置。

services
   .AddControllers()
   .AddJsonOptions(options =>
   
       options.JsonSerializerOptions.IgnoreNullValues = true;
   )
   .AddNewtonsoftJson(options =>
   
       options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
   );

【讨论】:

至少对于.NET Core 3.1,不需要调用AddJsonOptions,只需:.AddNewtonsoftJson(options => options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; ); 如果你使用 system.text.json 那么你需要。【参考方案6】:

如果您使用 System.Text.Json (.net 5.0) 并且您想忽略所有 null 使用WhenWritingNull条件:

services.AddControllers().AddJsonOptions(a =>
     
        a.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;            
        a.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
     );

【讨论】:

【参考方案7】:

查看官方迁移指南Migrate from ASP.NET Core 2.2 to 3.0

您的服务代码应如下所示:

services.AddMvc(c =>


)
.AddNewtonsoftJson(
    options =>
        
            options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            options.SerializerSettings.StringEscapeHandling = StringEscapeHandling.Escapehtml;                      

            options.SerializerSettings.Error = (object sender, ErrorEventArgs args) =>
            
               // handle error
            ;
        
    );

【讨论】:

如果您希望属性级别控制忽略空值,并且您不想经历编写自定义转换器的相当大的麻烦,那么使用 Newtonsoft.Json 是一种有效的方法。

以上是关于使用新的 Net Core 3.0 Json 时忽略属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 .NET core 3.0/System.text.Json 解析 JSON 文件

.Net Core 3.0原生Json解析器

在 .NET Core 3.0 中支持 Newtonsoft.Json 的使用

在Asp.Net Core 3.0中如何使用 Newtonsoft.Json 库序列化数据

.Net Core 3.0 JsonSerializer 填充现有对象

.Net Core 3.0 可执行文件不读取 appsettings.json