如何根据条件添加(可能为空)JSON 属性?
How to add a (possibly empty) JSON property, based on a condition?
昨天,我需要在 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);
万一在属性声明中做不到,这里可以做吗?
您的属性中不能有条件,请尝试在常规代码中设置这些条件默认值。 (属性只能有常量值)
您可以利用 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]()
returns true
;
时才会被序列化
另见 this fiddle
编辑
是的,你的JsonSerializerSettings
中的DefaultValueHandling.Ignore
可能确实对连载结果有影响。即,即使 ShouldSerialize...
returns true
,如果 属性 等于默认值,也不会被序列化(在这种特殊情况下, bool
将如果它是 false
并且设置了 DefaultValueHandling.Ignore
,则永远不会被序列化。
因此,如果您总是希望在 NAME
等于 i1
时序列化 i1ENABLE
,则必须为此 属性 覆盖 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
将 总是 被序列化,当 NAME == "i1"
但 永远不会 被序列化在 NAME != "i1"
时序列化
ShouldSerialize...
可能是最早的过滤器之一,它是在 属性 序列化期间完成的。如果它 returns false
,这个 属性 永远不会被序列化。但是如果是returnstrue
,还有其他检查。其中之一是 DefaultValueHandling
。因此,如果 DefaultValueHandling
设置为 Ignore
值 false
的布尔值将不会被序列化,即使 ShouldSerialize...
returns true.
另请参阅此 updated fiddle
昨天,我需要在 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);
万一在属性声明中做不到,这里可以做吗?
您的属性中不能有条件,请尝试在常规代码中设置这些条件默认值。 (属性只能有常量值)
您可以利用 json.net
的 Conditional Property Serializationclass 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]()
returns true
;
另见 this fiddle
编辑
是的,你的JsonSerializerSettings
中的DefaultValueHandling.Ignore
可能确实对连载结果有影响。即,即使 ShouldSerialize...
returns true
,如果 属性 等于默认值,也不会被序列化(在这种特殊情况下, bool
将如果它是 false
并且设置了 DefaultValueHandling.Ignore
,则永远不会被序列化。
因此,如果您总是希望在 NAME
等于 i1
时序列化 i1ENABLE
,则必须为此 属性 覆盖 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
将 总是 被序列化,当 NAME == "i1"
但 永远不会 被序列化在 NAME != "i1"
ShouldSerialize...
可能是最早的过滤器之一,它是在 属性 序列化期间完成的。如果它 returns false
,这个 属性 永远不会被序列化。但是如果是returnstrue
,还有其他检查。其中之一是 DefaultValueHandling
。因此,如果 DefaultValueHandling
设置为 Ignore
值 false
的布尔值将不会被序列化,即使 ShouldSerialize...
returns true.
另请参阅此 updated fiddle