1

I have a rather complex data model that gets serialized to and from XML. We all know that when C#'s XmlSerializer serializes the same instance of a object multiple times that objects data get duplicated. I am having an issue of one instance of an object not deserializing. For example, let's say we have three objects: A, B, C. Lets say that A contains two instances of B, and B contains an list of C.

A
->B
  ->List<C> -- This one deserializes
->B
  ->List<C> -- This one does not

When I deserialize object A, the first instance of B deserializes correctly. However, when I inspect the second instance of B the List<C> is empty. I have ran a difference compare on the sections XML and they are the same.

Does anyone know why one list would deserialize and not the other?

UPDATE

This is the best that I can pair down the problem. The original XML is about 110,000 lines long.

Classes:

[Serializable]
public class A
{
    public B instanceOne {get; set;}
    public B instanceTwo {get; set;}
}

[Serializable]
public class B : INotifyPropertyChanged
{
    private C _c;
    public ObservableCollection<C> C
    {
        get => _c;
        set
        {
            if(_c == value)
               return;
            _c = value;
            RaisePropertyChanged(nameof(C));
        }
   }
 //More Code
}

[Serializable, XmlRoot(ElementName = "MyC", Namespace = "MyNS")]
public class C
{
    public int value {get;set;}
}

XML output:

<?xml version="1.0"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <InstanceOne>
        <C>
          <Value xmlns="MyNS">10</Value>
        </C>
    </InstanceOne>
    <InstanceTwo>
        <C>
          <Value xmlns="MyNS">10</Value>
        </C>
    </InstanceTwo>
</A>

C# Deserialization Code

XmlSerializer xml = new XmlSerializer(typeof(A));

using (FileStream fs = File.OpenRead(@"C:\a.xml"))
{
    var t = xml.Deserialize(fs);
}
Travis Pettry
  • 1,220
  • 1
  • 14
  • 35
  • I'm sorry - do you mean to say classes, and not objects? Do you have two different objects of class B, or the same object "B" two times? – gnud Apr 06 '18 at 17:53
  • It would help if you showed the actual XML, and the code you use to serialize/deserialize, along with the relevant classes. – Ron Beyer Apr 06 '18 at 17:54
  • I more or less have an object that has two instances of the same object. I would share the XML but it's 113,000 lines long – Travis Pettry Apr 06 '18 at 17:55

2 Answers2

0

Lists should have proper XmlElement attributes along with names. And empty lists (without elements are skipped). It works on multiple levels. I reproduced this :

[Serializable]
public class A
{
    public A()
    {
        this.instanceOne = new B();
        this.instanceTwo = new B();
    }

    public B instanceOne { get; set; }
    public B instanceTwo { get; set; }
}

[Serializable]
public class B
{
    public B()
    {
        this._c = new C();
        this._c.value = 10;
    }

    private C _c;
}

[Serializable, XmlRoot(ElementName = "MyC", Namespace = "MyNS")]
public class C
{
    public int value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var serializer = new XmlSerializer(typeof(A));
        var a = new A();
        try
        {
            var fs = new System.IO.FileStream("test.xml", System.IO.FileMode.Create);
            serializer.Serialize(fs, a);
            fs.Close();
            A d = (A)serializer.Deserialize(new System.IO.FileStream("test.xml", System.IO.FileMode.Open));
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.ReadLine();
    }
}
Mirko Acimovic
  • 508
  • 2
  • 9
  • Well since you are using observable collections and files you must check if file is locked or you have a race condition. – Mirko Acimovic Apr 06 '18 at 18:54
  • Acimoic where would I find some resources on that topic? – Travis Pettry Apr 06 '18 at 18:59
  • Try similar problems here posted : https://stackoverflow.com/questions/12225853/why-my-observablecollection-serialization-doesnt-work?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa And also using lock() is the way to ensure that resource is in use. Since deserialize process is not the problem in single thread execution I think that you should mock a test case without ObsevableCollection first then if that works dig into async, await or lock() to make your code run in sync. – Mirko Acimovic Apr 06 '18 at 19:13
  • The one odd matter is, one collection deserializes while the other does not. – Travis Pettry Apr 06 '18 at 20:08
  • I have replaced the observable collections with lists and I get the same result. – Travis Pettry Apr 06 '18 at 20:16
  • I updated my answer with your code example. See how that fits into your full code. I can just guess that somehow file stays open or there is a problem with file itself since this works for me. It's hard to tell without debugging actual codebase. – Mirko Acimovic Apr 06 '18 at 20:45
0

I was not able to solve the issue at hand by calling the XmlSerializer. I ended up parsing the file then going back through the XML with the XmlReader to fill in the specific missing gaps.

Travis Pettry
  • 1,220
  • 1
  • 14
  • 35