2010-02-03 7 views
6

Ich verwende das .NET XSD.EXE-Importer, um C# -Klassen aus einer Sammlung von XSD-Dateien zu generieren. Als ich versuchte, eine der Klassen in XML zu serialisieren, scheiterte es (InvalidOperationException), und als ich mich darin vertiefte, entdeckte ich, dass eine der erstellten Klassen falsch zu sein scheint..NET xsd-Importer erstellt unserializable-Klasse

Hier ist die zugehörige 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> 

Und hier ist der C# -Code daraus generiert:

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; 
     } 
    } 
} 

Es machte Warnings ein Array aus einer Anordnung von WarningType. Wenn ich die XML serialisiert werden versuchen, erhalte ich eine InvalidOperationException Ausnahme:

  • Es kann keine temporäre Klasse (Ergebnis = 1) erzeugen.
  • CS0030 Fehler: kann nicht Typ konvertieren 'WarningType []' auf 'WarningType'
  • Fehler CS0030: konvertieren kann nicht Typ 'WarningType []' auf 'WarningType'
  • CS0029 Fehler: convert nicht implizit Typ Kann 'WarningType' zu ‚WarningType []‘
  • Fehler CS0029: Kann nicht implizit Typ umwandeln ‚WarningType‘ auf ‚WarningType []‘

Aber wenn ich den generierten Code WarningType[][]-WarningType[] dann ändern serialisiert es in Ordnung.

Kurz der Bearbeitung der generierten C# -Klasse, wann immer ich dies regeneriere (was hoffentlich weniger häufig vorwärts geht), gibt es eine andere Lösung? Ist das ein Fehler in xsd.exe oder ist die XSD-Datei falsch? Vielleicht gibt es ein Problem im XmlSerializer?

Was ich will ist C# -Code, der korrekt in XML serialisiert, die gegen die XSD validiert. Im Moment scheint das gezackte Array falsch zu sein, denn wenn ich es entferne, erzeugt es das XML.

ich Visual Studio 2008.

+0

Ich glaube, das ist ein bekannter Fehler, der nicht behoben wird. Siehe https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types für einen anderen XSD-Bug, von dem sie sagen, dass es nicht sein wird Fest. –

+0

@John Saunders - Bugger, das ist, was ich dachte. Gibt es eine gute Alternative zu XSD.exe, die Sie kennen? –

+0

Das Problem besteht immer noch in .NET 4.5.1 – yW0K5o

Antwort

4

Es gibt Fehler in dem xsd.exe Werkzeug verwenden. Ich erinnere mich nicht an diese besondere, aber ich erinnere mich daran, Probleme mit gezackten Arrays zu finden, und es ist möglich, dass dies ein Fehler bleibt. Wenn Sie dazu bereit sind, können Sie das Tool XsdObjbectGen verwenden, das ebenfalls von Microsoft stammt, aber unabhängig und out-of-band vom .NET-SDK bereitgestellt wird.

Eine Sache, die Sie tun könnten, ist die umgekehrte Richtung: Schreiben Sie den C# -Code, dann generieren Sie das Schema mit xsd.exe, und sehen Sie, was anders ist. Es ist möglich, dass xsd.exe das Schema so aussehen lässt, dass korrekter Code für gezackte Arrays korrekt generiert wird.


Eigentlich, nach dem Lesen Ihrer Frage, haben Sie nie gesagt, was Sie wirklich wollten. Soll der SuccessType ein Array-of-arrays enthalten oder nicht?

Und ist es WarningsType oder WarningType? Es gibt einige Unstimmigkeiten zwischen den bereitgestellten Code-Snips.


Vorausgesetzt, dass Sie die Array-of-Arrays wollte, schrieb ich diese 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; 
     } 
    } 
} 

... dann in eine DLL kompiliert. Dann lief ich xsd.exe auf dieser DLL und generiert dieses 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> 

... und Rundreisen. Wenn ich dann xsd.exe für dieses Schema ausführen, erhalte ich einen Typ, der ein array-of-arrays umschließt.

+0

Ich aktualisierte meine Frage, um klarer zu sein. Weißt du wo ich XSDObjectGen finde? –

+0

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

+0

Gibt es eine Version, die mit allem außer .NET 1.1 funktioniert? Ich kann nicht einmal das installieren. Ich werde dies bis zu einem Fehler blockieren: https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types –

Verwandte Themen