使用 C# 的条件 JSON 序列化

Conditional JSON serialization using C#

我有一个 class,我在 C# 中序列化为 JSON,post 序列化为 RESTful Web 服务。我有一个要求,如果一个字段已填写,则另一个字段不存在。如果两个字段都序列化到 JSON 对象中,则服务错误。我的 class 看起来像这样:

    [DataContract(Name = "test-object")]
public class TestObject
{
    [DataMember(Name = "name")]
    public string Name { get; set; }

    // If string-value is not null or whitespace do not serialize bool-value
    [DataMember(Name = "bool-value")]
    public bool BoolValue { get; set; }

    // If string-value is null or whitespace do not serialize it
    [DataMember(Name = "string-value")]
    public string StringValue { get; set; }
}

如评论中所述,如果 StringValue 有值,请不要将 BoolValue 放入 JSON 对象中。如果 StringValue 为空,则不要输入 StringValue 而是输入 BoolValue。

我找到了如何使用 XML 序列化来执行此操作,但找不到使用 JSON 序列化的方法。 C# 上是否有条件 JSON 序列化?

您似乎正在使用 DataContractJsonSerializer。在这种情况下,您可以:

  1. 禁用属性 [IgnoreDataMember] 的直接序列化。
  2. 创建用于序列化的代理 stringbool? 属性,当它们不应被序列化时 return 为 null。这些可以是 private.
  3. 在这些代理属性上设置 [DataMember(EmitDefaultValue=false)] 以禁止输出空值。

因此:

[DataContract(Name = "test-object")]
public class TestObject
{
    [DataMember(Name = "name")]
    public string Name { get; set; }

    [IgnoreDataMember]
    public bool BoolValue { get; set; }

    [IgnoreDataMember]
    public string StringValue { get; set; }

    bool ShouldSerializeStringValue()
    {
        return !String.IsNullOrWhiteSpace(StringValue);
    }

    // If string-value is not null or whitespace do not serialize bool-value
    [DataMember(Name = "bool-value", EmitDefaultValue=false)]
    bool? SerializedBoolValue {
        get
        {
            if (!ShouldSerializeStringValue())
                return BoolValue;
            return null;
        }
        set
        {
            BoolValue = (value ?? false); // Or don't set it at all if value is null - your choice.
        }
    }

    // If string-value is null or whitespace do not serialize it
    [DataMember(Name = "string-value", EmitDefaultValue=false)]
    string SerializedStringValue {
        get
        {
            if (ShouldSerializeStringValue())
                return StringValue;
            return null;
        }
        set
        {
            StringValue = value;
        }
    }
}

顺便说一句,这也适用于 Json.NET, which respects data contract attributes