【问题标题】:.NET xsd importer creates unserializable class.NET xsd 导入器创建不可序列化的类
【发布时间】:2010-02-03 00:45:13
【问题描述】:

我正在使用 .NET XSD.EXE 导入器从一组 XSD 文件中生成 C# 类。当我尝试将其中一个类序列化为 XML 时,它失败了(InvalidOperationException),当我深入研究它时,我发现其中一个创建的类似乎是错误的。

这里是相关的 XSD 代码:

<xsd:complexType name="SuccessType">
    <xsd:annotation>
        <xsd:documentation>Indicates in a response message that a request was successfully processed.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="Warnings" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>
<!-- .. snip .. -->
<xsd:element name="Warnings" type="WarningsType">
    <xsd:annotation>
        <xsd:documentation>The processing status of a business message and any related warnings or informational messages.</xsd:documentation>
    </xsd:annotation>
</xsd:element>
<!-- .. snip .. -->
<xsd:complexType name="WarningsType">
    <xsd:annotation>
        <xsd:documentation>A collection of warnings generated by the successful processing of a business message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="Warning" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>
<!-- .. snip .. -->
<xsd:element name="Warning" type="WarningType">
    <xsd:annotation>
        <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation>
    </xsd:annotation>
</xsd:element>
<!-- .. snip .. -->
<xsd:complexType name="WarningType">
    <xsd:annotation>
        <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="WarningCategory"/>
        <xsd:element ref="WarningCode"/>
        <xsd:element ref="WarningShortMessage"/>
        <xsd:element ref="WarningMessage"/>
    </xsd:sequence>
</xsd:complexType>

下面是从中生成的 C# 代码:

public partial class SuccessType
{

    private WarningType[][] warningsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType), IsNullable = false)]
    public WarningType[][] Warnings
    {
        get
        {
            return this.warningsField;
        }
        set
        {
            this.warningsField = value;
        }
    }
}

它使Warnings 成为WarningType 数组的数组。当我尝试将其序列化为 XML 时,我得到一个 InvalidOperationException 异常:

  • 无法生成临时类 (result=1)。
  • 错误 CS0030:无法将类型“WarningType[]”转换为“WarningType”
  • 错误 CS0030:无法将类型“WarningType[]”转换为“WarningType”
  • 错误 CS0029:无法将类型“WarningType”隐式转换为“WarningType[]”
  • 错误 CS0029:无法将类型“WarningType”隐式转换为“WarningType[]”

但是,如果我将生成的代码从 WarningType[][] 更改为 WarningType[],那么它可以很好地序列化。

每当我重新生成它时都没有编辑生成的 C# 类(希望以后不会那么频繁),还有其他解决方案吗?这是 xsd.exe 中的错误还是 XSD 文件不正确?可能是 XmlSerializer 有问题?

我想要的是正确序列化为针对 XSD 进行验证的 XML 的 C# 代码。现在锯齿状数组似乎是错误的,因为如果我删除它,它就会生成 XML。

我正在使用 Visual Studio 2008。

【问题讨论】:

  • 我相信这是一个无法修复的已知错误。请参阅 connect.microsoft.com/VisualStudio/feedback/details/362727/… 了解他们说不会修复的另一个 XSD 错误。
  • @John Saunders - 臭虫,这就是我的想法。有没有你知道的 XSD.exe 的好替代品?
  • .NET 4.5.1 中问题依然存在

标签: c# .net xml xsd invalidoperationexception


【解决方案1】:

xsd.exe 工具中存在错误。我不记得这个特别的,但我记得发现了锯齿状数组的问题,这可能仍然是一个错误。如果您愿意,您可以使用同样来自 Microsoft 的 XsdObjbectGen 工具,但它是独立于 .NET SDK 的带外发布的。

您可以做的一件事是反其道而行之:编写 C# 代码,然后使用 xsd.exe 生成架构,看看有什么不同。 xsd.exe 可能希望架构具有特定的外观,以便为锯齿状数组正确生成正确的代码。


实际上,在重新阅读您的问题后,您从未说出您真正想要的内容。您是否希望 SuccessType 包含数组数组?

它是 WarningsType 还是 WarningType?您提供的代码片段之间存在一些分歧。


假设您想要数组数组,我编写了以下 C# 代码:

public class WarningType
{
    public String oof;
}


public partial class SuccessType
{
    private WarningType[][] warningsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType[]), IsNullable = false)]
    public WarningType[][] Warnings
    {
        get
        {
            return this.warningsField;
        }
        set
        {
            this.warningsField = value;
        }
    }
}

... 然后将其编译为 DLL。然后我在那个 DLL 上运行 xsd.exe,并生成了这个 XSD:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="WarningType" nillable="true" type="WarningType" />
  <xs:complexType name="WarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="oof" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="SuccessType" nillable="true" type="SuccessType" />
  <xs:complexType name="SuccessType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Warnings" type="ArrayOfArrayOfWarningType" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfArrayOfWarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Warning" type="ArrayOfWarningType" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfWarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="WarningType" nillable="true" type="WarningType" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

...它往返。如果我然后在该架构上运行 xsd.exe,我会得到一个包含数组数组的类型。

【讨论】:

猜你喜欢
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2015-04-03
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多