6

我正在从 .NET Core 3.0 应用程序迁移Newtonsoft.JsonSystem.Text.Json。我试图忽略错误值。

System.Text.Json我发现忽略空值的选项:

JsonSerializerOptions.IgnoreNullValues = true;

但我找不到忽略System.Text.Json.

有人知道如何做到这一点System.Text.Json吗?

或者,如果有人知道相当于 Newtonsoft 的DefaultValueHandling = DefaultValueHandling.Ignore选项,那也太棒了。

4

1 回答 1

7

这是在.Net 5.0中实现的:

支持忽略值类型默认值

这个版本引入了JsonIgnoreCondition枚举:

/// When specified on JsonSerializerOptions.DefaultIgnoreCondition,
/// determines when properties and fields across the type graph are ignored.
/// When specified on JsonIgnoreAttribute.Condition, controls whether
/// a property is ignored during serialization and deserialization. This option
/// overrides the setting on JsonSerializerOptions.DefaultIgnoreCondition.
public enum JsonIgnoreCondition
{
    /// Property is never ignored during serialization or deserialization.
    Never = 0,
    /// Property is always ignored during serialization and deserialization.
    Always = 1,
    /// If the value is the default, the property is ignored during serialization.
    /// This is applied to both reference and value-type properties and fields.
    WhenWritingDefault = 2,
    /// If the value is <see langword="null"/>, the property is ignored during serialization.
    /// This is applied only to reference-type properties and fields.
    WhenWritingNull = 3,
}

具体JsonIgnoreCondition.WhenWritingDefault将抑制false布尔值。它可以以两种方式之一应用。首先,您可以使用以下方法将其直接应用于成员JsonIgnoreAttribute.Condition

public class Model
{
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public bool Value { get; set; }
}

演示小提琴#1在这里

其次,您可以将其设置为JsonSerializerOptions.DefaultIgnoreCondition

指定一个条件来确定在序列化或反序列化期间何时忽略具有默认值的属性。默认值为从不

即给出以下模型:

public class Model
{
    public bool Value { get; set; }
}

您可以按如下方式对其进行序列化,以false在运行时跳过值的序列化:

var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };
var json = JsonSerializer.Serialize(model, options);

演示小提琴#2在这里

笔记:

  1. .Net 5.0 文档JsonIgnoreCondition似乎有一些不准确之处。首先,他们声称这WhenWritingDefault意味着

    仅当属性为 时才会被忽略null

    但是,实际上如果按照源代码default中的说明,该属性将被忽略。

    其次,他们声称WhenWritingNull

    仅适用于引用类型的属性和字段。

    但是,测试表明它也适用于可为的值类型成员。例如给定模型:

    public class Model
    {
        public bool? Value { get; set; }
    }
    

    当它为空时DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault省略序列化:Value

    var model = new Model(); // Leave value null
    
    var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };
    Console.WriteLine(JsonSerializer.Serialize(model, options)); // Prints {}
    

    演示小提琴#3在这里

  2. 设置不仅JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault适用于所有值类型bool。因此,如果您有任何double, int, DateTime, decimal(包括具有指定位数的零值小数,例如decimal.Parse("0.0000"))或其他值类型成员,则当值等于默认值时,它们将被省略。

    似乎没有一种方法可以在全局跳过仅默认bool值成员的序列化同时仍然序列化其他值类型成员,这可以通过自定义合同解析器在 Json.NET 中完成。

    演示小提琴#4在这里

  3. 在确定成员是否具有默认值时,使用值类型的默认值(即default(T))。与Json.NET不同,DefaultValueAttribute不考虑在内。

    演示小提琴#5在这里

  4. 在 .Net 5.0 之前,您需要为包含类型创建自定义JsonConverter(即Model在上面的示例中)并根据需要手动跳过或序列化每个成员。

于 2020-11-16T20:58:06.917 回答