2010-02-03 52 views
6

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

下面是相关的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; 
     } 
    } 
} 

它使WarningsWarningType阵列的阵列。当我尝试序列化到XML,我得到一个InvalidOperationException例外:

  • 无法生成临时类(结果= 1)。
  • 错误CS0030:无法将类型 'WarningType []' 到 'WarningType'
  • 错误CS0030:无法将类型 'WarningType []' 到 'WarningType'
  • 错误CS0029:无法隐式转换类型 'WarningType' 来'WarningType []'
  • 错误CS0029:无法隐式转换类型 'WarningType' 到 'WarningType []'

但是,如果我生成的代码从WarningType[][]WarningType[]更改然后将其序列罚款。

无论何时重新生成(希望将不再频繁前进)编辑生成的C#类的缺点,是否还有其他解决方案?这是xsd.exe中的错误还是XSD文件不正确?也许在XmlSerializer中有问题?

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

我正在使用Visual Studio 2008.

+0

我相信这是一个已知的bug,不会被修复。请参阅https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types了解他们认为不会出现的另一个XSD错误固定。 – 2010-02-06 01:31:17

+0

@约翰桑德斯 - 布吉尔,那就是我想的。您知道XSD.exe是否有很好的选择? – 2010-02-06 01:53:36

+0

.NET 4.5.1中仍然存在此问题 – yW0K5o 2015-03-02 16:36:36

回答

4

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

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


其实,在重读您的问题时,您从未说过您真正想要的东西。你想让SuccessType包含一个数组的数组吗?

而且是WarningsTypeWarningType?你提供的代码片段之间存在一些分歧。


假设你想要的阵列的阵列,我写了这个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,则会得到一个封装了数组数组的类型。

+0

我更新了我的问题,以便更清楚。你知道我在哪里可以找到XSDObjectGen吗? – 2010-02-06 01:36:07

+0

xsdobjectgen:http://www.microsoft.com/downloads/details.aspx?familyid=89e6b1e5-f66c-4a4d-933b-46222bb01eb0&displaylang=en – Cheeso 2010-02-06 02:19:59

+0

是否有一个版本可以与.NET 1.1以外的任何版本兼容?我甚至无法安装那个。我要把这个问题塞满一个bug:https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types – 2010-02-08 17:31:16