2010-02-03 15 views
6

Estoy usando el importador .NET XSD.EXE para generar clases C# de una colección de archivos XSD. Cuando traté de serializar una de las clases en XML falló (InvalidOperationException), y cuando busqué en ella, descubrí que una de las clases creadas parece estar equivocada..NET xsd importador crea la clase no serializable

Este es el código XSD pertinente:

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

Y aquí es el código C# generada a partir de ella:

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

Se hizo Warnings una matriz de un conjunto de WarningType. Cuando intento para serializar a XML que obtengo una excepción InvalidOperationException:

  • No se puede generar una clase temporal (resultado = 1).
  • CS0030 de error: No se puede convertir tipo 'WarningType []' a 'WarningType'
  • CS0030
  • de error: No se puede convertir tipo 'WarningType []' a 'WarningType'
  • CS0029
  • de error: No se puede convertir implícitamente el tipo 'WarningType' a 'WarningType []'
  • error CS0029: no se puede convertir implícitamente el tipo 'WarningType' a 'WarningType []'

Pero si cambio el código generado a partir de WarningType[][] a WarningType[] entonces se serializa bien.

A falta de editar la clase C# generada cada vez que regenere esto (que con suerte será menos frecuente en el futuro), ¿hay alguna otra solución? ¿Es esto un error en xsd.exe o el archivo XSD es incorrecto? Tal vez hay un problema en el XmlSerializer?

Lo que quiero es un código de C# que serializa correctamente a XML que valida contra el XSD. En este momento, la matriz dentada parece estar equivocada porque si la elimino, genera el XML.

Estoy utilizando Visual Studio 2008.

+0

Creo que este es un error conocido que no se solucionará. Consulte https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types para otro error de XSD que dicen que no será fijo. –

+0

@ John Saunders - Bugger, eso es lo que pensé. ¿Hay una buena alternativa a XSD.exe que conozcas? –

+0

El problema todavía existe en .NET 4.5.1 – yW0K5o

Respuesta

4

hay errores en la herramienta xsd.exe. No recuerdo esta en particular, pero recuerdo haber encontrado problemas con arreglos irregulares, y es posible que esto siga siendo un error. si lo desea, puede usar la herramienta XsdObjbectGen, también de Microsoft, pero lanzada de forma independiente y fuera de banda desde .NET SDK.

Una cosa que podría hacer es ir en la dirección opuesta: escriba el código C#, luego genere el esquema con xsd.exe y vea qué es diferente. Es posible que xsd.exe quiera que el esquema se vea de una manera particular, a fin de generar correctamente el código correcto para matrices irregulares.


En realidad, al volver a leer su pregunta, nunca dijo lo que realmente quería. ¿Desea que SuccessType contenga una matriz de matrices o no?

¿Y es WarningsType o WarningType? Hay un desacuerdo entre los recortes de código que proporcionó.


Suponiendo que quería la matriz de-arrays, escribí este código 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; 
     } 
    } 
} 

... entonces compilado en un archivo DLL. Entonces me encontré con xsd.exe en esa DLL, y generaron esta 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> 

... y viajes redondos. Si luego ejecuto xsd.exe en ese esquema, obtengo un tipo que envuelve una matriz de arreglos.

+0

Actualicé mi pregunta para ser más clara. ¿Sabes dónde puedo encontrar XSDObjectGen? –

+0

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

+0

¿Hay alguna versión que funcione con algo más que .NET 1.1? Ni siquiera puedo instalarlo. Voy a solucionar esto con un error: https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types –

Cuestiones relacionadas