如何使用 System.Text.Json 忽略错误值

ste*_*evo 6 c# json json.net .net-core system.text.json

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

System.Text.Json我找到了忽略空值的选项:

JsonSerializerOptions.IgnoreNullValues = true;
Run Code Online (Sandbox Code Playgroud)

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

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

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

dbc*_*dbc 5

这是在.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,
}
Run Code Online (Sandbox Code Playgroud)

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

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

演示小提琴 #1在这里

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

指定一个条件来确定在序列化或反序列化过程中何时忽略具有默认值的属性。默认值为Never

即给出以下模型:

public class Model
{
    public bool Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };
var json = JsonSerializer.Serialize(model, options);
Run Code Online (Sandbox Code Playgroud)

演示小提琴 #2在这里

笔记:

  1. 净5.0文档的JsonIgnoreCondition出现有一定的误差。首先,他们声称这WhenWritingDefault意味着

    属性只有在是 时才会被忽略null

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

    其次,他们声称 WhenWritingNull

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

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

    /// 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,
    }
    
    Run Code Online (Sandbox Code Playgroud)

    当它为空时使用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 {}
    
    Run Code Online (Sandbox Code Playgroud)

    演示小提琴 #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 之前,您需要为包含类型(即在上面的示例中)创建自定义JsonConverterModel并根据需要手动跳过或序列化每个成员。