Parece que hay un error conocido en wsdl.exe, la herramienta que Visual Studio usa para generar proxies de servicios web. Con ciertos esquemas XSD, la herramienta generará clases que no se pueden deserializar del XML.¿Cómo puedo arreglar el proxy de referencia web que generó Visual Studio para manejar arreglos irregulares?
Por lo que a mí respecta, eso es inaceptable, pero no sé cómo solucionarlo.
Describiré mi caso en detalle, espero que alguien pueda ayudarme con eso.
esquema
<!-- return type from the service operation -->
<xs:complexType name="listAssetsQueryResults">
<xs:sequence>
<xs:element name="assets" type="tns:asset" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- a sequence of attributes -->
<xs:complexType name="asset">
<xs:sequence>
<xs:element name="attributes" type="tns:multiValuedAttribute" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="multiValuedAttribute">
<!-- not relevant-->
</xs:complexType>
respuesta XML del servicio web
Una respuesta típica de acuerdo con este esquema es el siguiente:
<assets-query-result>
<assets>
<attributes>
<name>Keywords</name>
<values>Desert</values>
</attributes>
<attributes>
<name>Filename</name>
<values>Desert.jpg</values>
</attributes>
</assets>
<assets>...</assets>
<assets>...</assets>
</assets-query-result>
Utilizando los tipos de código de
que hubiera esperado a ser capaz de utilizar los tipos CLR así:
result.assets[0].attributes[0].name
En cambio, el tipo generado por el resultado tiene el siguiente aspecto:
[SerializableAttribute()]
public partial class listAssetsQueryResults {
private multiValuedAttribute[][] assetsField;
[XmlArrayAttribute(Form=XmlSchemaForm.Unqualified, IsNullable=true)]
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets {
get { return this.assetsField; }
set { this.assetsField = value; }
}
}
Lo cual no tiene ni siquiera ¡permita que se genere el ensamble de serialización!
No se puede convertir tipo Portfolio.WebService.multiValuedAttribute a Portfolio.WebService.multiValuedAttribute []
Arreglándolo
1 - Cambiar el tipo de la propiedad y campo
Ahora una de las soluciones que encontré en línea es simplemente eliminar un par de corchetes del tipo de la generación rados propiedad:
// No longer a jagged array, but this doesn't deserialize all data
public multiValuedAttribute[] assets;
Eso permite que el ensamblado de serialización que se construirá, y se ejecuta sin excepciones, excepto que no serializa los datos correctamente, 'salta' la lista de activos y deserializa los atributos del primer assets
elemento. Entonces no es una solución, porque con esta corrección no puedo consumir los datos. Para más de 700 activos, da result.assets
es igual a multiValuedAttribute[2]
(los 2 elementos son los atributos de nombre y palabras clave del primer activo).
2 - Especificación del tipo de los elementos de XML-
La segunda cosa que probé es dar deserializador diferentes instrucciones:
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute[]), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets { ... }
Así que ahora estoy diciéndole que cada elemento de la la secuencia es del tipo multiValuedAttribute[]
.Eso está mal porque todavía está mirando elementos attributes
, que son del tipo multiValuedAttribute
(solo, no una matriz). Sin embargo, se ejecuta, pero ahora el result.assets
es igual a multiValuedAttribute[2][0]
y aún no puedo acceder a los datos.
¿Qué sigue?
No tengo ni idea, razón por la cual escribí esto. No puedo aceptar que .NET no pueda consumir este servicio web, porque tiene que hacerlo.
¿Alguna vez llegar a una mejor solución para esto? Estoy frente a la cuestión exacta, pero tengo cientos de tipos que necesitaría la modificación de –