我有一个JObject
用作html" target="_blank">调用RESTful Web服务的 模板
。这JObject
是通过解析器创建的,由于它被用作告诉用户端点模式的模板,因此我不得不想出一种保留所有属性的方法,这就是为什么将其默认值设置为的原因null
。作为示例,这是对象最初的外观:
{
"Foo":{
"P1":null,
"P2":null,
"P3":null,
"P4":{
"P1":null,
"P2":null,
"P3":null,
},
"FooArray":[
{
"F1":null,
"F2":null,
"F3":null,
}
]
},
"Bar":null
}
然后,用户可以根据需要填写各个字段,例如Foo.P2
和Foo.P4.P1
:
{
"Foo":{
"P1":null,
"P2":"hello world",
"P3":null,
"P4":{
"P1":1,
"P2":null,
"P3":null,
},
"FooArray":[
{
"F1":null,
"F2":null,
"F3":null,
}
]
},
"Bar":null
}
表示他们只关心这两个领域。现在,我想将此模板(JObject
)序列化回一个JSON字符串,但只希望显示填充的那些字段。所以我尝试了这个:
string json = JsonConvert.SerializeObject(template,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
不幸的是,这没有用。我遇到了这个问题,并意识到null
对象中的值是实际JToken
类型,而不是真正的anull
,这很有意义。但是,在这种非常特殊的情况下,我需要能够摆脱这些“未使用”的字段。我尝试过手动遍历节点并删除它们,但这也不起作用。注意,我使用的唯一托管类型是JObject
;
我没有将对象转换为对象或在其上定义属性的模型,因为此“模板”在运行时已解析。我只是想知道是否有人遇到过这样的问题并且有任何见解。任何帮助是极大的赞赏!
您可以使用一种类似于下面的递归帮助器方法来在序列化之前null
从JToken
层次结构中删除值。
using System;
using Newtonsoft.Json.Linq;
public static class JsonHelper
{
public static JToken RemoveEmptyChildren(JToken token)
{
if (token.Type == JTokenType.Object)
{
JObject copy = new JObject();
foreach (JProperty prop in token.Children<JProperty>())
{
JToken child = prop.Value;
if (child.HasValues)
{
child = RemoveEmptyChildren(child);
}
if (!IsEmpty(child))
{
copy.Add(prop.Name, child);
}
}
return copy;
}
else if (token.Type == JTokenType.Array)
{
JArray copy = new JArray();
foreach (JToken item in token.Children())
{
JToken child = item;
if (child.HasValues)
{
child = RemoveEmptyChildren(child);
}
if (!IsEmpty(child))
{
copy.Add(child);
}
}
return copy;
}
return token;
}
public static bool IsEmpty(JToken token)
{
return (token.Type == JTokenType.Null);
}
}
演示:
string json = @"
{
""Foo"": {
""P1"": null,
""P2"": ""hello world"",
""P3"": null,
""P4"": {
""P1"": 1,
""P2"": null,
""P3"": null
},
""FooArray"": [
{
""F1"": null,
""F2"": null,
""F3"": null
}
]
},
""Bar"": null
}";
JToken token = JsonHelper.RemoveEmptyChildren(JToken.Parse(json));
Console.WriteLine(token.ToString(Formatting.Indented));
输出:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
},
"FooArray": [
{}
]
}
}
小提琴:https :
//dotnetfiddle.net/wzEOie
请注意,删除所有空值后,您可能会在中有一个空对象FooArray
,您可能不需要。(如果删除了该对象,则FooArray
可能会有一个空值,您可能也不想这样做。)如果要使helper方法在删除它时更加主动,则可以将IsEmpty函数更改为:
public static bool IsEmpty(JToken token)
{
return (token.Type == JTokenType.Null) ||
(token.Type == JTokenType.Array && !token.HasValues) ||
(token.Type == JTokenType.Object && !token.HasValues);
}
进行适当的更改后,您的输出将如下所示:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
}
}
}
小提琴:https://dotnetfiddle.net/ZdYogJ
问题内容: 我有一个简单的接口与属性的getter和setter。 我还有另一个实现此接口的UserAccount类。 我的问题是我想序列化money属性,但在反序列化它时忽略它,即,不接受用户对此属性的任何值。我在setter上尝试过@JsonIgnore,在getter上尝试过@JsonIgnore(false),它确实会忽略它,但是在序列化它时也会这样做。 我在setter上尝试了@Json
我有另一个类UserAccount实现了这个接口。 我的问题是,我想序列化money属性,但在反序列化时忽略它,即不接受用户对该属性的任何值。我在setter上尝试了@jsonIgnore,在getter上尝试了@jsonIgnore(false),它确实忽略了它,但是它在序列化它的同时也忽略了它。 我在setter上尝试了@jsonIgnore,在getter上尝试了@jsonProperty,
问题内容: 我正在使用Json.Net将类序列化和反序列化为json并返回。 我在标有(或)新的仅获取属性的类中添加了代码。结果如下: Newtonsoft.Json.JsonSerializationException:在JSON中找不到必需的属性 我以为标记该属性可以解决此问题,但这不起作用。 我如何告诉Json.Net应该忽略此属性? 这是重现此问题的最小示例: 问题答案: 显然,在这种情况
问题内容: 在这个例子中 如果JSON对象缺少属性“ age”, 有人说它不能反序列化。在反序列化期间是否有 注释 可以忽略丢失的字段? 谢谢 问题答案: 我想你想要的是 这就是Jackson 1.x的方式。我认为2.x中有一种新方法。就像是 这些将告诉Jackson仅序列化不为null的值,并且在反序列化缺少的值时不会抱怨。我认为它将只是将其设置为Java默认值。
问题内容: 我如何才能序列化一个特定的属性,但又防止其反序列化回POCO?是否可以使用属性装饰特定属性? 基本上,我正在寻找一个与ShouldSerialize *方法等效的反序列化方法。 我知道我可以编写一个自定义转换器,但是这样做似乎有点过头了。 编辑: 这里还有一些背景。这背后的原因是我的课看起来像: 我需要请求的属性,但是我不希望它反序列化并触发设置程序逻辑。 问题答案: 最简单的方法是将
我想在Java中反序列化包含空值的json字符串。我想将对象反序列化为对象。json字符串类似于: 当我反序列化使用 由于对象中的that,我得到一个空指针异常。我如何指示Gson忽略空值的反序列化?