question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

List<T> with complex objects (referential integrity, parameterized content) is not deserialized properly

See original GitHub issue

Hey 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.

interconnected node graph

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 ] Null was added to outer list
  • Node 2 does not link back to node 1 Missing link from node 2 to node 1
  • Node 3 does not link to node 2 Missing link from node 3 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:closed
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
feO2xcommented, Jul 21, 2020

Thanks for your efforts, I will take a look at it tomorrow!

1reaction
Mike-E-angelocommented, Jul 21, 2020

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. 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' ...
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'test.Model.RetrieveMultipleResponse' because the type requires a JSON object ...
Read more >
How to Deserialize a Complex JSON Object in C# .NET
In this article, we are gonig to learn how to deserialize a complex JSON object using C# as our language of choice.
Read more >
Deserialization should not be vulnerable to injection attacks
Deserialization injections occur when applications deserialize wholly or partially untrusted data without verification.
Read more >
Deserialize json which has a string and complex object
Hi, I am trying to deserialize a json string and write its content into a datatable. I have the following json string with...
Read more >
How do i use the deserialized JSON data and what is ...
Now the code that reads the JSON file. I have two solutions for that, one being a more "complex" one and a "simpler"...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found