Первое, что приходит на ум, - это циклические зависимости.
Допустим, у нас есть класс, у которого есть поле, ссылающееся на его потомка, а у дочернего класса есть поле, ссылающееся на его родителя.
public class A
{
public B Child;
}
public class B
{
public A Parent;
}
public class Program
{
private static void Main()
{
A a = new A();
B b = new B();
a.Child = b;
b.Parent = a;
string json = JsonConvert.SerializeObject(a);
}
}
Это может вызвать время выполнения JsonSerializationException
в JsonConvert.SerializeObject(a)
со следующим сообщением:
Self referencing loop detected for property 'Parent' with type 'A'. Path 'Child'.
Чтобы избежать этого, JSON.NET предоставляет перегрузку SerializeObject
передать объект настроек, где мы можем указать, как обрабатывать циклические ссылки.
JsonSerializerSettings settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
JsonConvert.SerializeObject(a, settings);
Таким образом, выходной json будет полностью игнорировать циклическую ссылку от дочернего элемента к родительскому, и он будет выглядеть следующим образомэто:
{
"Child": {}
}
JSON.NET также предоставляет способ обрабатывать их без потери информации.Нам нужно указать в настройках опцию PreserveReferencesHandling.Objects
.
JsonSerializerSettings settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
Выходной JSON может интерпретироваться только JSON.NET или другими сериализаторами, совместимыми с синтаксисом $id
и $ref
,и это будет выглядеть так:
{
"$id":"1",
"Child": {
"$id":"2",
"Parent": {
"$ref":"1"
}
}
}