如何序列化和反序列化的JSON对象到一定深度在C#中? [英] How to serialize or deserialize a JSON Object to a certain depth in C#?
问题描述
我只想要一个对象(我不希望任何儿童)的第一深度水平。我愿意用任何可用的库。当到达递归深度大多数图书馆只会抛出只是忽略了一个例外,而不是。如果这是不可能的,有没有办法忽略某些成员的序列化给予一定的数据类型?
编辑: 比方说,我有一个对象,像这样:
类的MyObject
{
字符串名称=丹;
INT年龄= 88;
名单<儿童> myChildren = ...(很多孩子有很多孙辈的);
}
我想删除所有儿童(复杂类型偶数)返回一个对象是这样的:
类的MyObject
{
字符串名称=丹;
INT年龄= 88;
名单<儿童> myChildren = NULL;
}
这是可能的 Json.NET 使用一些之间的<协调href="http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonWriter.htm"><$c$c>JsonWriter$c$c>和串行的<一个href="http://james.newtonking.com/projects/json/help/ContractResolver.html"><$c$c>ContractResolver$c$c>.
自定义 JsonWriter
递增一个对象时启动计数器,然后当它结束时再次将它减。
公共类CustomJsonTextWriter:JsonTextWriter
{
公共CustomJsonTextWriter(的TextWriter的TextWriter):基地(的TextWriter){}
公众诠释CurrentDepth {获得;私定; }
公众覆盖无效WriteStartObject()
{
CurrentDepth ++;
base.WriteStartObject();
}
公众覆盖无效WriteEndObject()
{
CurrentDepth--;
base.WriteEndObject();
}
}
自定义 ContractResolver
采用特殊<一个href="http://james.newtonking.com/projects/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_ShouldSerialize.htm"><$c$c>ShouldSerialize$c$c> predicate上,将被用于验证当前深度的所有属性。
公共类CustomContractResolver:DefaultContractResolver
{
私人只读Func键&LT;布尔&GT; _includeProperty;
公共CustomContractResolver(Func键&LT;布尔&GT; includeProperty)
{
_includeProperty = includeProperty;
}
保护覆盖JsonProperty CreateProperty(
的MemberInfo成员,MemberSerialization memberSerialization)
{
VAR属性= base.CreateProperty(成员,memberSerialization);
VAR shouldSerialize = property.ShouldSerialize;
property.ShouldSerialize = OBJ =&GT; _includeProperty()&安培;&安培;
(shouldSerialize == NULL ||
shouldSerialize(物镜));
返回财产;
}
}
下面的方法显示了这两个自定义类是如何协同工作。
公共静态字符串SerializeObject(obj对象,诠释MAXDEPTH)
{
使用(VAR strWriter =新的StringWriter())
{
使用(VAR jsonWriter =新CustomJsonTextWriter(strWriter))
{
FUNC&LT;布尔&GT;包括=()=&GT; jsonWriter.CurrentDepth&LT; = MAXDEPTH;
VAR解析器=新CustomContractResolver(含);
无功序列化=新JsonSerializer {ContractResolver =解析器};
serializer.Serialize(jsonWriter,OBJ);
}
返回strWriter.ToString();
}
}
下面的测试code说明分别限制了最大深度为1和2的水平。
VAR OBJ =新节点{
NAME =一,
儿童=新节点{
名称=两节,
儿童=新节点{
NAME =三化
}
}
};
变种TXT1 = SerializeObject(物镜,1);
变种TXT2 = SerializeObject(物镜,2);
公共类节点
{
公共字符串名称{;组; }
公众子节点{获得;组; }
}
I only want the first depth level of an object (I do not want any children). I am willing to use any library available. Most libraries will merely throw an exception when the recursion depth is reached, instead of just ignoring. If this isn't possible, is there a way to ignore serialization of certain members given a certain datatype?
Edit: Let's say I have an object like so:
class MyObject
{
String name = "Dan";
int age = 88;
List<Children> myChildren = ...(lots of children with lots of grandchildren);
}
I want to remove any children (complex types even) to return an object like this:
class MyObject
{
String name = "Dan";
int age = 88;
List<Children> myChildren = null;
}
This is possible in Json.NET using some coordination between the JsonWriter
and the serializer's ContractResolver
.
A custom JsonWriter
increments a counter when an object is started and then decrements it again when it ends.
public class CustomJsonTextWriter : JsonTextWriter
{
public CustomJsonTextWriter(TextWriter textWriter) : base(textWriter) {}
public int CurrentDepth { get; private set; }
public override void WriteStartObject()
{
CurrentDepth++;
base.WriteStartObject();
}
public override void WriteEndObject()
{
CurrentDepth--;
base.WriteEndObject();
}
}
A custom ContractResolver
applies a special ShouldSerialize
predicate on all properties that will be used to verify the current depth.
public class CustomContractResolver : DefaultContractResolver
{
private readonly Func<bool> _includeProperty;
public CustomContractResolver(Func<bool> includeProperty)
{
_includeProperty = includeProperty;
}
protected override JsonProperty CreateProperty(
MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var shouldSerialize = property.ShouldSerialize;
property.ShouldSerialize = obj => _includeProperty() &&
(shouldSerialize == null ||
shouldSerialize(obj));
return property;
}
}
The following method shows how these two custom classes work together.
public static string SerializeObject(object obj, int maxDepth)
{
using (var strWriter = new StringWriter())
{
using (var jsonWriter = new CustomJsonTextWriter(strWriter))
{
Func<bool> include = () => jsonWriter.CurrentDepth <= maxDepth;
var resolver = new CustomContractResolver(include);
var serializer = new JsonSerializer {ContractResolver = resolver};
serializer.Serialize(jsonWriter, obj);
}
return strWriter.ToString();
}
}
The following test code demonstrates limiting the maximum depth to 1 and 2 levels respectively.
var obj = new Node {
Name = "one",
Child = new Node {
Name = "two",
Child = new Node {
Name = "three"
}
}
};
var txt1 = SerializeObject(obj, 1);
var txt2 = SerializeObject(obj, 2);
public class Node
{
public string Name { get; set; }
public Node Child { get; set; }
}
这篇关于如何序列化和反序列化的JSON对象到一定深度在C#中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!