如何根据条件添加(可能为空)JSON 属性?

问题描述 投票:0回答:2

昨天,我需要在 JSON 文件中添加一个属性,我已经使用

DefaultHandling
完成了此操作,如上一个问题中所述:

[JsonProperty("DIAGNOSTICS", DefaultValueHandling = DefaultValueHandling.Populate)]
public bool DIAGNOSTICS { get; set; }

现在我正在处理一个更复杂的情况:

我的源代码摘录:

[JsonProperty("NAME")]
public string NAME { get; set; }
[JsonProperty("i1.ENABLE")]
public bool i1ENABLE { get; set; }
[JsonProperty("i2.ENABLE")]
public bool i2ENABLE { get; set; }
[JsonProperty("i3ENABLE")]
public bool i3ENABLE { get; set; }
...

所需的 JSON 结果:

"NAME": "i1",
"i1.ENABLE": false, /* i2.ENABLE and i3.ENABLE are not shown */
...
"NAME": "i2",
"i2.ENABLE": false, /* i1.ENABLE and i3.ENABLE are not shown */
...
"NAME": "i3",
"i3.ENABLE": false, /* i1.ENABLE and i2.ENABLE are not shown */
...

所以我的问题是,这可能吗(伪代码),如果是的话,怎么办?

[JsonProperty("i1.ENABLE", DefaultValueHandling = (IF(NAME=="i1") THEN DefaultValueHandling.Populate))]
public bool i1ENABLE { get; set; }
[JsonProperty("i2.ENABLE", DefaultValueHandling = (IF(NAME=="i2") THEN DefaultValueHandling.Populate))]
public bool i2ENABLE { get; set; }
[JsonProperty("i3.ENABLE", DefaultValueHandling = (IF(NAME=="i3") THEN DefaultValueHandling.Populate))]
public bool i3ENABLE { get; set; }

编辑(在Laurent第一次回答之后)

我的序列化代码如下:

JsonSerializerSettings js = new JsonSerializerSettings();
js.DefaultValueHandling = DefaultValueHandling.Ignore;
string temp = JsonConvert.SerializeObject(root, Formatting.Indented, js);

如果在属性声明中做不到,可以在这里做吗?

c# json serialization json.net
2个回答
2
投票

你的属性中不能有条件。
尝试在常规代码中设置这些条件默认值。 (属性只能有常量值)


1
投票

您可以利用 json.net 的 Conditional Property Serialization

class CC {
  [JsonProperty("NAME")]
  public string NAME { get; set; }

  [JsonProperty("i1.ENABLE")]
  public bool i1ENABLE { get; set; }

  [JsonProperty("i2.ENABLE")]
  public bool i2ENABLE { get; set; }

  [JsonProperty("i3.ENABLE")]
  public bool i3ENABLE { get; set; }

  public bool ShouldSerializei1ENABLE() {
    bool r = NAME == "i1";
    return r;
  }

  public bool ShouldSerializei2ENABLE() {
    bool r = NAME == "i2";
    return r;
  }

  public bool ShouldSerializei3ENABLE() {
    bool r = NAME == "i3";
    return r;
  }

}

因此,只有当

ShouldSerialize[PropertyName]()
返回
true
;

时,属性才会被序列化

另请参阅这个小提琴

编辑

是的,你的

DefaultValueHandling.Ignore
中的
JsonSerializerSettings
确实可能会对序列化的结果产生影响。即,即使
ShouldSerialize...
返回
true
,如果属性等于默认值,也不会被序列化(在这种特殊情况下,如果
bool
false
并且
DefaultValueHandling.Ignore
则永远不会被序列化)设置)。

因此,如果您总是想在

i1ENABLE
等于
NAME
时序列化
i1
,则必须重写此属性的
DefaultValueHandling

class CC {
  [JsonProperty("NAME")]
  public string NAME { get; set; }

  [JsonProperty("i1.ENABLE", DefaultValueHandling=DefaultValueHandling.Populate)]
  public bool i1ENABLE { get; set; }

  public bool ShouldSerializei1ENABLE() {
    bool r = NAME == "i1";
    return r;
  }
}

所以当你按如下方式序列化时

JsonSerializerSettings js = new JsonSerializerSettings();
js.DefaultValueHandling = DefaultValueHandling.Ignore;
string temp = JsonConvert.SerializeObject(root, Formatting.Indented, js);

属性

i1ENABLE
always被序列化,当
NAME == "i1"
从不
NAME != "i1"

时被序列化

ShouldSerialize...
可能是第一个过滤器,它是在属性序列化期间完成的。如果它返回
false
,则该属性永远不会序列化。但如果返回
true
,则还有其他检查。其中之一是
DefaultValueHandling
。因此,如果
DefaultValueHandling
设置为
Ignore
,则即使
false
返回 true,也不会序列化值为
ShouldSerialize...
的布尔值。

另请参阅此更新的小提琴

© www.soinside.com 2019 - 2024. All rights reserved.