反序列化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

反序列化XSD时出现StackOverflowException

如果该代码段是构造函数,则使用直接递归。第一行创建了一个相同类型的对象,它调用了相同的构造函数。

基本上,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

将与上面的其他代码一样,导致它在火花中爆炸:

在序列化类别类型的对象时检测到循环引用。

然而,递归模式本身工作得很好

相关文章:
  • 没有找到相关文章