.NET xsd导入器创建不可序列化的类

时间:2022-12-30 17:19:19

I am using the .NET XSD.EXE importer to generate C# classes from a collection of XSD files. When I tried to serialize one of the classes to XML it failed (InvalidOperationException), and when I dug into it I discovered it one of the created classes appears to be wrong.

我使用.NET XSD.EXE导入程序从XSD文件集合生成C#类。当我尝试将其中一个类序列化为XML时,它失败了(InvalidOperationException),当我挖到它时,我发现其中一个创建的类看起来是错误的。

Here is the pertinent XSD code:

以下是相关的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>

And here is the C# code generated from it:

这是从它生成的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;
        }
    }
}

It made Warnings an array of an array of WarningType. When I attempt to serialize that to XML I get an InvalidOperationException exception:

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

  • Unable to generate a temporary class (result=1).
  • 无法生成临时类(result = 1)。
  • error CS0030: Cannot convert type 'WarningType[]' to 'WarningType'
  • 错误CS0030:无法将类型'WarningType []'转换为'WarningType'
  • error CS0030: Cannot convert type 'WarningType[]' to 'WarningType'
  • 错误CS0030:无法将类型'WarningType []'转换为'WarningType'
  • error CS0029: Cannot implicitly convert type 'WarningType' to 'WarningType[]'
  • 错误CS0029:无法将类型'WarningType'隐式转换为'WarningType []'
  • error CS0029: Cannot implicitly convert type 'WarningType' to 'WarningType[]'
  • 错误CS0029:无法将类型'WarningType'隐式转换为'WarningType []'

But if I change the generated code from WarningType[][] to WarningType[] then it serializes fine.

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

Short of editing the generated C# class whenever I regenerate this (which hopefully will be less frequently going forward), is there any other solution? Is this a bug in xsd.exe or is the XSD file incorrect? Maybe there is a problem in the XmlSerializer?

每当我重新生成这个时,编辑生成的C#类(希望将来不那么频繁),还有其他解决方案吗?这是xsd.exe中的错误还是XSD文件不正确?也许XmlSerializer存在问题?

What I want is C# code that correctly serializes to XML that validates against the XSD. Right now the jagged array seems to be wrong because if I remove it then it generates the XML.

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

I am using Visual Studio 2008.

我正在使用Visual Studio 2008。

1 个解决方案

#1


4  

There are bugs in the xsd.exe tool. I don't remember this particular one, but I do remember finding problems with jagged arrays, and it's possible this remains a bug. if you're willing, you could use the XsdObjbectGen tool, also from Microsoft, but released independently and out-of-band from the .NET SDK.

xsd.exe工具中有bug。我不记得这个特别的,但我确实记得发现锯齿状阵列的问题,这可能仍然是一个错误。如果您愿意,可以使用同样来自Microsoft的XsdObjbectGen工具,但可以从.NET SDK中独立发布并带外发布。

One thing you could do is go the reverse direction: write the C# code, then generate the schema with xsd.exe, and see what is different. It's possible xsd.exe wants the schema to look a particular way, in order to correctly generate correct code for jagged arrays.

你可以做的一件事是反向:编写C#代码,然后用xsd.exe生成模式,看看有什么不同。 xsd.exe可能希望模式以特定方式呈现,以便为锯齿状数组正确生成正确的代码。


Actually, upon re-reading your question, you never said what you really wanted. Do you want SuccessType to contain an array-of-arrays, or not?

实际上,在重新阅读你的问题时,你从未说过你真正想要的东西。您是否希望SuccessType包含数组数组?

And is it WarningsType or WarningType? There's some disagreement between the code snips you provided.

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


Assuming you wanted the array-of-arrays, I wrote this C# code:

假设你想要数组数组,我写了这个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;
        }
    }
}

... then compiled it into a DLL. Then I ran xsd.exe on that DLL, and generated this XSD:

...然后将其编译成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>

...and it round-trips. If I then run xsd.exe on that schema, I get a type that wraps an array-of-arrays.

......它往返了。如果我然后在该模式上运行xsd.exe,我得到一个包装数组数组的类型。

#1


4  

There are bugs in the xsd.exe tool. I don't remember this particular one, but I do remember finding problems with jagged arrays, and it's possible this remains a bug. if you're willing, you could use the XsdObjbectGen tool, also from Microsoft, but released independently and out-of-band from the .NET SDK.

xsd.exe工具中有bug。我不记得这个特别的,但我确实记得发现锯齿状阵列的问题,这可能仍然是一个错误。如果您愿意,可以使用同样来自Microsoft的XsdObjbectGen工具,但可以从.NET SDK中独立发布并带外发布。

One thing you could do is go the reverse direction: write the C# code, then generate the schema with xsd.exe, and see what is different. It's possible xsd.exe wants the schema to look a particular way, in order to correctly generate correct code for jagged arrays.

你可以做的一件事是反向:编写C#代码,然后用xsd.exe生成模式,看看有什么不同。 xsd.exe可能希望模式以特定方式呈现,以便为锯齿状数组正确生成正确的代码。


Actually, upon re-reading your question, you never said what you really wanted. Do you want SuccessType to contain an array-of-arrays, or not?

实际上,在重新阅读你的问题时,你从未说过你真正想要的东西。您是否希望SuccessType包含数组数组?

And is it WarningsType or WarningType? There's some disagreement between the code snips you provided.

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


Assuming you wanted the array-of-arrays, I wrote this C# code:

假设你想要数组数组,我写了这个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;
        }
    }
}

... then compiled it into a DLL. Then I ran xsd.exe on that DLL, and generated this XSD:

...然后将其编译成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>

...and it round-trips. If I then run xsd.exe on that schema, I get a type that wraps an array-of-arrays.

......它往返了。如果我然后在该模式上运行xsd.exe,我得到一个包装数组数组的类型。