反序列化XSD时出现StackOverflowException
本文关键字:StackOverflowException XSD 反序列化 | 更新日期: 2023-09-27 18:16:42
我有以下模式,它具有Category递归。我尝试使用Xsd2Code来为这个模式生成Class。当我试图反序列化它时,我得到StackOverFlow异常。
在类的构造中有:
public category()
{
this.catField = new category();
this.channelField = new List<categoryChannel>();
}
这就是为什么我猜它会如此。
我做错了什么?谢谢!
<?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>
误差An unhandled exception of type 'System.StackOverflowException' occurred in XXX.dll
如果该代码段是构造函数,则使用直接递归。第一行创建了一个相同类型的对象,它调用了相同的构造函数。
基本上,xsd2code是做错了(参见构造函数中MizardX的答案了解原因)。
作为复制,我使用:
xsd foo.xsd /classes
来生成类(而不是xsd2code),那么下面的基本示例绝对没问题:
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);
}
}
选项:
- 使用xsd.exe,而不是xsd2code 提交xsd2code的bug报告
- 可能手动修复xsd2code生成的构造函数,这样它就不会创建子
category
这里递归的另一个可能原因很简单:使你的模型递归!例如:
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
将与上面的其他代码一样,导致它在火花中爆炸:
在序列化类别类型的对象时检测到循环引用。
然而,递归模式本身工作得很好