Reputation: 5802
I have the following schema, which is has Category recursive. I tried using Xsd2Code in order to generate Class for this schema. When I try to deserialize it, I am getting StackOverFlow exception.
In the construction of the class there is:
public category()
{
this.catField = new category();
this.channelField = new List<categoryChannel>();
}
that's why I guess it is going SO.
What am I doing wrong??? thanks!
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:complexType name="category">
<xs:sequence>
<xs:element name="channel" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:int"/>
</xs:complexType>
</xs:element>
<xs:element name="cat" type="category" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:element name="MH_CategoriesTree">
<xs:complexType>
<xs:sequence>
<xs:element name="response">
<xs:complexType>
<xs:sequence>
<xs:element name="cat" type="category"/>
</xs:sequence>
<xs:attribute name="type"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
the error
An unhandled exception of type 'System.StackOverflowException' occurred in XXX.dll
Upvotes: 0
Views: 533
Reputation: 1064044
Basically, xsd2code is doing it wrong (see MizardX's answer for why, in the constructor).
As a repro, I used:
xsd foo.xsd /classes
to generate classes (rather than xsd2code), then the following basic example works absolutely fine:
using System;
using System.IO;
using System.Xml.Serialization;
static class Program
{
static void Main()
{
MH_CategoriesTree root = new MH_CategoriesTree(), clone;
root.response = new MH_CategoriesTreeResponse();
root.response.type = "alpha";
root.response.cat = new category
{
cat = new category
{
cat = new category
{
channel = new categoryChannel[]
{
new categoryChannel { id = 123, idSpecified = true }
}
},
channel = new categoryChannel [0]
},
channel = new categoryChannel[]
{
new categoryChannel { id = 456, idSpecified = true},
new categoryChannel { id = 789, idSpecified = true },
}
};
var ser = new XmlSerializer(typeof(MH_CategoriesTree));
string xml;
using(var sw = new StringWriter())
{
ser.Serialize(sw, root);
xml = sw.ToString();
}
using(var sr = new StringReader(xml))
{
clone = (MH_CategoriesTree) ser.Deserialize(sr);
}
// now write "clone" to Console, to show it all worked
ser.Serialize(Console.Out, clone);
}
}
So options:
category
Another possible cause of recursion here is simply: to make your model recursive! for example:
MH_CategoriesTree root = new MH_CategoriesTree(), clone;
root.response = new MH_CategoriesTreeResponse();
root.response.type = "alpha";
var cat = new category();
cat.cat = cat;
root.response.cat = cat; // now we have an infinite loop
which will, with the rest of the code as-above, cause it to explode in a shower of sparks:
A circular reference was detected while serializing an object of type category.
However, a recursive schema itself works just fine.
Upvotes: 1
Reputation: 89231
If that code snippet is a constructor, you have direct recursion. The first line creates an object of the same type, which calls the same constructor.
Upvotes: 3