Error deserializando documento XML con XSD fuertemente tipado

Tengo un problema bastante molesto al intentar deserializar un documento XML específico utilizando el método XmlSerializer.Deserialize ().

Básicamente, tengo un XSD fuertemente tipado con un elemento de tipo doble. Cuando bash deserializar el elemento para un documento XML específico, obtengo la habitual “System.FormatException: la cadena de entrada no tenía el formato correcto”. excepción porque en ese documento específico, el elemento no tiene un valor.

Aquí hay un código para los nerds que hay.

Ejemplo de documento XML:

 Barcelona 4591   

XSD:

            

Clase TrackInfo:

 [Serializable] public class TrackInfo { private string name = string.Empty; private double length = 0.0; private double averageSpeed = 0.0; [XmlElement] public string Name { ... } [XmlElement] public double Length { ... } [XmlElement] public double AverageSpeed { ... } } 

Código de deserialización de muestra:

 XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load("TrackInfo.xml"); // Deserialise XML string into TrackInfo object byte[] buffer = ASCIIEncoding.UTF8.GetBytes(xmlDocument.InnerXml); MemoryStream stream = new MemoryStream(buffer); System.Xml.XmlReader reader = new System.Xml.XmlTextReader(stream); XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(TrackInfo)); TrackInfo trackInfo = (TrackInfo)xSerializer.Deserialize(reader); 

Sé que la excepción de deserialización proviene del hecho de que una cadena vacía no se puede convertir a doble. También sé que el valor predeterminado no está asignado a AverageSpeed ​​porque, efectivamente, una cadena vacía es un valor perfectamente aceptable.

¿Existe una manera fácil de establecer valores dobles predeterminados a 0.0 (o cualquier otro tipo) cuando se deserializa si se encuentra un valor de cadena vacía en el documento XML? Idealmente, me gustaría evitar la implementación de ISerializable porque realmente no tengo ganas de pasar el rest del día en el foso del infierno (es decir, la implementación de ISerializable para unas cien clases).

¡Aclamaciones! Jean-Michel

Puede especificar el valor predeterminado como

  [XmlElement] [System.ComponentModel.DefaultValueAttribute(0.0)] public double AverageSpeed { ... } 

/ edit: ok, extraño beaviour aquí. Lo que establezca como valor en el atributo es siempre el valor de los campos:

 private double averageSpeed = 2.0; 

Pero no se produce ninguna excepción.

Consulte la documentación de MSDN en DefaultValueAttribute: http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

Nota: un DefaultValueAttribute no hará que un miembro se inicialice automáticamente con el valor del atributo. Debe establecer el valor inicial en su código.

Creo que la inicialización del campo siempre tendrá prioridad sobre el valor DefaultValueAttribute. En cualquier caso, esto parece ser exactamente lo que estaba buscando.

Muchas gracias a ti Sebastian!

¿Una posible solución sería usar doble? (con el signo de interrogación, o Nullable ). Esto permite que su tipo de valor almacene un valor nulo, y el deserializador no se ahogue con un valor nulo.

Podría editar el esquema para especificar que el valor de AverageSpeed ​​no es anulable. Esto requiere que todo lo que produce el XML siga el esquema, por supuesto.