問題描述
我正在使用 .NET XSD.EXE 導入器生成來自 XSD 文件集合的 C# 類.當我嘗試將其中一個類序列化為 XML 時,它失敗了(InvalidOperationException),當我深入研究它時,我發現其中一個創建的類似乎是錯誤的.
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.
這里是相關的 XSD 代碼:
Here is the pertinent XSD code:
<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# 代碼:
And here is the C# code generated from it:
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
異常:
It made Warnings
an array of an array of WarningType
. When I attempt to serialize that to XML I get an InvalidOperationException
exception:
- 無法生成臨時類 (result=1).
- 錯誤 CS0030:無法將類型WarningType[]"轉換為WarningType"
- 錯誤 CS0030:無法將類型WarningType[]"轉換為WarningType"
- 錯誤 CS0029:無法將類型WarningType"隱式轉換為WarningType[]"
- 錯誤 CS0029:無法將類型WarningType"隱式轉換為WarningType[]"
但是如果我將生成的代碼從 WarningType[][]
更改為 WarningType[]
那么它可以很好地序列化.
But if I change the generated code from WarningType[][]
to WarningType[]
then it serializes fine.
每當我重新生成它時都沒有編輯生成的 C# 類(希望以后不會那么頻繁),還有其他解決方案嗎?這是 xsd.exe 中的錯誤還是 XSD 文件不正確?可能是 XmlSerializer 有問題?
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?
我想要的是正確序列化為針對 XSD 進行驗證的 XML 的 C# 代碼.現在鋸齒狀數組似乎是錯誤的,因為如果我刪除它,它就會生成 XML.
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.
我正在使用 Visual Studio 2008.
I am using Visual Studio 2008.
推薦答案
xsd.exe工具有bug.我不記得這個特別的,但我記得發現了鋸齒狀數組的問題,這可能仍然是一個錯誤.如果您愿意,可以使用 XsdObjbectGen 工具,同樣來自 Microsoft,但獨立于 .NET SDK 帶外發布.
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.
您可以做的一件事是反其道而行之:編寫 C# 代碼,然后使用 xsd.exe 生成架構,看看有什么不同.xsd.exe 可能希望架構具有特定的外觀,以便為鋸齒狀數組正確生成正確的代碼.
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.
實際上,在重新閱讀您的問題后,您從未說出您真正想要的內容.您是否希望 SuccessType 包含數組數組?
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?
它是 WarningsType 還是 WarningType?您提供的代碼片段之間存在一些分歧.
And is it WarningsType or WarningType? There's some disagreement between the code snips you provided.
假設您想要數組數組,我編寫了以下 C# 代碼:
Assuming you wanted the array-of-arrays, I wrote this C# code:
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:
... then compiled it into a DLL. Then I ran xsd.exe on that DLL, and generated this 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,我會得到一個包含數組數組的類型.
...and it round-trips. If I then run xsd.exe on that schema, I get a type that wraps an array-of-arrays.
這篇關于.NET xsd 導入器創建不可序列化的類的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!