Skip to content

Commit b6c9dbe

Browse files
committed
moving json related stuff out of the core
1 parent e9f1132 commit b6c9dbe

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using Newtonsoft.Json;
4+
using Newtonsoft.Json.Linq;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
9+
namespace PartialResponse.AspNetCore.Mvc.Formatters.Json.Internal
10+
{
11+
internal static class JsonSerializerExtensions
12+
{
13+
public static void Serialize(this JsonSerializer jsonSerializer, JsonWriter jsonWriter, object value, Func<string, bool> shouldSerialize)
14+
{
15+
if (value == null)
16+
{
17+
jsonSerializer.Serialize(jsonWriter, value);
18+
}
19+
else
20+
{
21+
var token = JToken.FromObject(value, jsonSerializer);
22+
23+
var array = token as JArray;
24+
25+
if (array != null)
26+
{
27+
RemoveArrayElements(array, null, shouldSerialize, new Dictionary<string, bool>());
28+
29+
array.WriteTo(jsonWriter);
30+
}
31+
else
32+
{
33+
var @object = token as JObject;
34+
35+
if (@object != null)
36+
{
37+
RemoveObjectProperties(@object, null, shouldSerialize, new Dictionary<string, bool>());
38+
39+
@object.WriteTo(jsonWriter);
40+
}
41+
else
42+
{
43+
token.WriteTo(jsonWriter);
44+
}
45+
}
46+
}
47+
}
48+
49+
private static void RemoveArrayElements(JArray array, string currentPath, Func<string, bool> shouldSerialize, Dictionary<string, bool> cache)
50+
{
51+
array.OfType<JObject>()
52+
.ToList()
53+
.ForEach(childObject => RemoveObjectProperties(childObject, currentPath, shouldSerialize, cache));
54+
55+
RemoveArrayIfEmpty(array);
56+
}
57+
58+
private static void RemoveArrayIfEmpty(JArray array)
59+
{
60+
if (array.Count == 0)
61+
{
62+
if (array.Parent is JProperty && array.Parent.Parent != null)
63+
{
64+
array.Parent.Remove();
65+
}
66+
else if (array.Parent is JArray)
67+
{
68+
array.Remove();
69+
}
70+
}
71+
}
72+
73+
private static void RemoveObjectProperties(JObject @object, string currentPath, Func<string, bool> shouldSerialize, Dictionary<string, bool> cache)
74+
{
75+
@object.Properties()
76+
.Where(property =>
77+
{
78+
var path = CombinePath(currentPath, property.Name);
79+
80+
if (cache.ContainsKey(path))
81+
{
82+
return cache[path];
83+
}
84+
85+
var result = !shouldSerialize(path);
86+
87+
cache.Add(path, result);
88+
89+
return result;
90+
})
91+
.ToList()
92+
.ForEach(property => property.Remove());
93+
94+
@object.Properties()
95+
.Where(property => property.Value is JObject)
96+
.ToList()
97+
.ForEach(property =>
98+
{
99+
var path = CombinePath(currentPath, property.Name);
100+
101+
RemoveObjectProperties((JObject)property.Value, path, shouldSerialize, cache);
102+
});
103+
104+
@object.Properties()
105+
.Where(property => property.Value is JArray)
106+
.ToList()
107+
.ForEach(property =>
108+
{
109+
var path = CombinePath(currentPath, property.Name);
110+
111+
RemoveArrayElements((JArray)property.Value, path, shouldSerialize, cache);
112+
});
113+
114+
RemoveObjectIfEmpty(@object);
115+
}
116+
117+
private static void RemoveObjectIfEmpty(JObject @object)
118+
{
119+
if (!@object.Properties().Any())
120+
{
121+
if (@object.Parent is JProperty && @object.Parent.Parent != null)
122+
{
123+
@object.Parent.Remove();
124+
}
125+
else if (@object.Parent is JArray)
126+
{
127+
@object.Remove();
128+
}
129+
}
130+
}
131+
132+
private static string CombinePath(string path, string name)
133+
{
134+
if (string.IsNullOrEmpty(path))
135+
{
136+
return name;
137+
}
138+
139+
return string.Format("{0}/{1}", path, name);
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)