List<T> with complex objects (referential integrity, parameterized content) is not deserialized properly
See original GitHub issueHey guys, thanks for ExtendedXmlSerializer and the love and effort you put into it, I really think it’s a great XML serializer.
I’m currently testing if ExtendedXmlSerializer is able to handle a complex object graph for a new project. This project uses a node graph that can be cyclic. Each node has a list of all linked nodes, and these links can either be unidirectional (if only one of two nodes links to the other one) or bidirectional (if both nodes link to each other).
I tried to serialize and deserialize this object graph with ExtendedXmlSerializer, but I encountered an issue. Please take a look at the following test (which uses xunit and FluentAssertions):
public sealed class MissingItemsInCollectionTests
{
private readonly ITestOutputHelper _output;
public MissingItemsInCollectionTests(ITestOutputHelper output) => _output = output;
[Fact]
public void NodesListIsMissingNodes()
{
var xmlSerializer = new ConfigurationContainer().UseOptimizedNamespaces()
.EnableParameterizedContentWithPropertyAssignments()
.UseAutoFormatting()
.Type<Node>()
.EnableReferences(node => node.Id)
.Create();
var node1 = new Node(1);
var node2 = new Node(2).AddNode(node1, isBidirectional: true);
var node3 = new Node(3).AddNode(node2, isBidirectional: false);
node1.AddNode(node3, isBidirectional: false);
var nodesList = new List<Node> { node1, node2, node3 };
var xml = xmlSerializer.Serialize(new XmlWriterSettings { Indent = true, IndentChars = " " }, nodesList);
_output.WriteLine(xml);
var deserializedNodesList = xmlSerializer.Deserialize<List<Node>>(xml);
deserializedNodesList.Should().BeEquivalentTo(nodesList, config => config.IgnoringCyclicReferences());
}
public sealed class Node : IEquatable<Node>
{
private readonly List<Node> _linkedNodes;
public Node(int id) : this(id, null) { }
public Node(int id, List<Node> linkedNodes)
{
Id = id;
_linkedNodes = linkedNodes ?? new List<Node>();
}
public int Id { get; }
public IReadOnlyList<Node> LinkedNodes => _linkedNodes;
public Node AddNode(Node otherNode, bool isBidirectional = true)
{
if (otherNode == null)
throw new ArgumentNullException(nameof(otherNode));
if (ReferenceEquals(this, otherNode))
throw new ArgumentException($"You cannot link a node {Id} to itself.");
_linkedNodes.Add(otherNode);
if (isBidirectional)
otherNode.AddNode(this, false);
return this;
}
public bool Equals(Node other) => !ReferenceEquals(null, other) && Id == other.Id;
public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is Node other && Equals(other);
public override int GetHashCode() => Id;
public override string ToString() => "Node " + Id;
}
}
In this test, i create three instances of the Node
class and interconnect them. Node 1 has a bidirectional link to node 2 and a unidirectional link to node 3, node 3 links unidirectionally to node 2.
When I run this test, the produced XML looks fine, but when the I deserialize the XML back to an object graph, then the following stuff happens:
deserializedNodesList
contains [ node 1, null, null ]- Node 2 does not link back to node 1
- Node 3 does not link to node 2
What keeps me wondering is that the link collections contain the right amount of entries, but all of them are null instead of the corresponding deserialized node instance. Did I forget to configure something properly, or is this is a bug in ExtendedXmlSerializer? Does this have something to do with https://github.com/ExtendedXmlSerializer/home/issues/360 (although no structs are involved)?
Thanks for your help in advance.
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (5 by maintainers)
Top GitHub Comments
Thanks for your efforts, I will take a look at it tomorrow!
Hey there @feO2x … good news! I managed to figure out what is wrong here and have your test above passing in our suite now:
https://github.com/ExtendedXmlSerializer/home/blob/f3e47dae82f76e1a73ddb9de3d14a1feefed4176/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue396Tests.cs#L12-L32
If interested, you can check out the build here:
https://github.com/ExtendedXmlSerializer/home/pull/421#issuecomment-661998115
Thought I would let you know. Please let me know if you run into any further problems and I can look into it for you. Re-opening and will close when pushed to NuGet. 👍