Ari*_*edi 13 c# json json.net nsjsonserialization
我有一个JObject用作调用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
}
Run Code Online (Sandbox Code Playgroud)
然后,用户能够填补他们需要单独的领域,如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
}
Run Code Online (Sandbox Code Playgroud)
意思是他们只关心这两个领域.现在我想将此模板(JObject)序列化为JSON字符串,但只想要填充的那些字段显示出来.所以我尝试了这个:
string json = JsonConvert.SerializeObject(template,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用.我遇到了这个问题,并意识到null对象中的值是一个实际JToken类型,而不是真正的类型null,这是有道理的.但是,在这种非常特殊的情况下,我需要能够摆脱这些"未使用"的字段.我尝试手动迭代节点并删除它们,但这也不起作用.请注意,我使用的唯一托管类型是JObject; 我没有将对象转换为或定义属性的模型,因为此"模板"在运行时得到解析.我只是想知道是否有人遇到过这样的问题并且有任何见解.任何帮助是极大的赞赏!
Bri*_*ers 19
您可以使用类似下面的递归帮助方法在序列化之前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);
}
}
Run Code Online (Sandbox Code Playgroud)
演示:
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));
Run Code Online (Sandbox Code Playgroud)
输出:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
},
"FooArray": [
{}
]
}
}
Run Code Online (Sandbox Code Playgroud)
小提琴: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);
}
Run Code Online (Sandbox Code Playgroud)
有了这个改变,你的输出将会是这样的:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
}
}
}
Run Code Online (Sandbox Code Playgroud)
小提琴:https://dotnetfiddle.net/ZdYogJ
| 归档时间: |
|
| 查看次数: |
7680 次 |
| 最近记录: |