I wish to serialize a collection (List<Item>
) of items to JSON.
These items have a collection of Connection
which gives information about the connection from one Item
to a second Item
. And since the connection object has a reference to the items it makes it an infinite loop.
My question is is there a way for me to skip serialization of the connection collection when serializing the object the second time.
I've tried things like inheriting from JsonConverter
and writing a custom WriteJson()
method but from there I have no sence whether I should write out the array or not.
I've also tried using a custom ContractResolver but with no good results.
Classes
public class Item
{
private static int _lastID = 0;
public Item()
{
ID = ++_lastID;
Connections = new List<Connection>();
}
public int ID { get; set; }
public string Name { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public List<Connection> Connections { get; set; }
}
public class Connection
{
private Connection(ConnectionType type, Item source, Item target)
{
if (type == ConnectionType.None)
throw new ArgumentException();
if (source == null)
throw new ArgumentNullException("source");
if (target == null)
throw new ArgumentNullException("target");
Type = type;
Source = source;
Target = target;
}
public ConnectionType Type { get; set; }
public Item Source { get; set; }
public Item Target { get; set; }
public static void Connect(ConnectionType type, Item source, Item target)
{
var conn = new Connection(type, source, target);
source.Connections.Add(conn);
target.Connections.Add(conn);
}
}
Wanted result:
[
{
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2",
"connections": {
"type": "ConnType",
"source": {
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2"
// no connections array
},
"target": {
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2"
// no connections array
}
}
},
{
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2",
"connections": {
"type": "ConnType",
"source": {
"id": 1,
"name": "Item #1",
"prop1": "val1",
"prop2": "val2"
// no connections array
},
"target": {
"id": 2,
"name": "Item #2",
"prop1": "val1",
"prop2": "val2"
// no connections array
}
}
}
]
EDIT:
C#
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented
};
settings.Converters.Add(new StringEnumConverter());
var json = JsonConvert.SerializeObject(collection, settings);
Add this to your Global.asax (or in the WebApiConfig or any other config class)
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
If I'm not mistaken you need to keep only the first depth of reference containing the connection collection? If that is the case, try using:
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
settings.MaxDepth = 1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With