0

I want to serialize a class into an XML file. My class has subclasses that contain many circular references, for this I use the DataContractSerializer. Over all classes the attribute IsReferenze = true is set.

Unfortunately I always get a stackoverflow exception when serializing. Do I have to pay attention to something with the DataContractSerializer or does it simply reach its limits with many circular references and lists? It works for a few entries, but after a certain number it doesn't work anymore.

Example:

[DataContract(IsReference = true)]
public class ParentClass
{
    [DataMember] public ConcurrentDictionary<string, A> Dict{ get; set; } = new ConcurrentDictionary<string, A>();
    [DataMember] public List<B> List1 { get; set; } = new List<B>();
    [DataMember] public List<B> List2 { get; set; } = new List<B>();
    [DataMember] public List<B> List3 { get; set; } = new List<B>();
    [DataMember] public List<B> List4 { get; set; } = new List<B>();
    [DataMember] public List<B> List5 { get; set; } = new List<B>();
    [DataMember] public List<C> List6 { get; set; } = new List<C>();
    [DataMember] public List<C> List7 { get; set; } = new List<C>();
    [DataMember] public List<C> List8 { get; set; } = new List<C>();
}

[DataContract(IsReference=true)]
public class A
{
    [DataMember] public string Text { get; set; }
    [DataMember] public List<B> List1 { get; set; } = new List<B>();
    [DataMember] public List<B> List2 { get; set; } = new List<B>();
    [DataMember] public List<B> List3 { get; set; } = new List<B>();
    [DataMember] public List<B> List4 { get; set; } = new List<B>();
    [DataMember] public List<C> List5 { get; set; } = new List<C>();
}

[DataContract(IsReference=true)]
public class B
{
    [DataMember] public List<A> List1 { get; set; } = new List<A>();
    [DataMember] public List<string> List2 { get; set; } = new List<string>();
    [DataMember] public List<B> List3 { get; set; } = new List<B>();
    [DataMember] public List<B> List4 { get; set; } = new List<B>();

}

[DataContract(IsReference=true)]
public class C
{
    [DataMember] public string Id { get; set; }
    [DataMember] public string Text { get; set; }
    [DataMember] public List<B> List1 { get; set; } = new List<B>();
    [DataMember] public List<B> List2 { get; set; } = new List<B>();
    [DataMember] public List<C> List3 { get; set; } = new List<C>();
}


private void Serialize()
{            
    var ds = new DataContractSerializer(typeof(ParentClass));
    var settings = new XmlWriterSettings { Indent = true };

    using (var w = XmlWriter.Create(@"test.xml", settings))
    {
        ds.WriteObject(w, ParentClassObject);          
    }
}

Does anyone have an idea?

Best regards!

shermes
  • 11
  • 1
  • 2
  • Reference tracking serializes the first occurrence of any object encountered in the serialization graph, and I *believe* that `DataContractSerializer` is a depth-first serializer. So if your object graph is extremely deep -- e.g. you are serializing a linked list -- this might happen. See [JSON.NET StackOverflowException while serialization](https://stackoverflow.com/a/41841581/3744182) for a similar-sounding problem with Json.NET. – dbc Apr 16 '21 at 01:51
  • Or maybe not, maybe you have a real bug. Can you share a [mcve] with an instance of `ParentClassObject` that reproduces the problem? – dbc Apr 16 '21 at 01:51

0 Answers0