2008-11-03 17 views
14

Estoy usando XmlSerializer para escribir y leer un objeto a xml en C#. Actualmente uso los atributos XmlElement y XmlIgnore para manipular la serialización del objeto.¿Puedo dejar de deserializar con XmlSerializer en C# si no se encuentra un elemento?

Si a mi archivo xml le falta un elemento xml que requiera, mi objeto todavía se deserializa (xml -> object) muy bien. ¿Cómo señalo (preferiblemente a través de Atributos) que cierto campo es "requerido"?

Aquí es un método muestra de lo que estoy utilizando actualmente:

[XmlElement(ElementName="numberOfWidgets")] 
public int NumberThatIsRequired { 
    set ...; 
    get ...; 
} 

Mi solución ideal sería añadir algo así como un atributo XmlRequired.

Además, ¿hay una buena referencia de qué atributos están disponibles para manipular el comportamiento de XmlSerializer?

+0

Pregunta msdn similar [aquí] (http://social.msdn.microsoft.com/Forums/eu/xmlandnetfx/thread/a134471c-6b20-433e-8dd4-d153cac29810) que también explica que la validación es lo que estás intentando para hacer – KCD

+0

si no tiene el elemento 'numberOfWidgets' en el XML, ¿qué tendrá en la propiedad NumberThatIsRequired? ¿cero? –

Respuesta

4

Tengo una respuesta para la segunda parte: "Attributes that control XML serialization".

sigue investigando la primera parte ...

EDIT: Tengo la firme sospecha que no se puede hacer esto por sí mismo deserialización XML. Acabo de ejecutar xsd.exe en un esquema de muestra que incluye un atributo obligatorio, y es exactamente lo mismo si el atributo está marcado como opcional. Si hubiera una manera de exigir el establecimiento de propiedades, esperaría que se implementara en ese caso.

Sospecho que básicamente tienes que validar tu árbol de objetos después de deserializarlo. Lo siento por eso ...

+0

Necesita tener un espacio de nombres XML configurado correctamente en su XML fuente al que también se hace referencia en su XSD, o la validación con un XSD no funcionará correctamente, incluida la validación de campo requerida. –

15

La única manera que he encontrado para hacerlo es a través de XSD. Lo que puede hacer es validar mientras deserializar:

static T Deserialize<T>(string xml, XmlSchemaSet schemas) 
{ 
    //List<XmlSchemaException> exceptions = new List<XmlSchemaException>(); 
    ValidationEventHandler validationHandler = (s, e) => 
    { 
     //you could alternatively catch all the exceptions 
     //exceptions.Add(e.Exception); 
     throw e.Exception; 
    }; 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.Schemas.Add(schemas); 
    settings.ValidationType = ValidationType.Schema; 
    settings.ValidationEventHandler += validationHandler; 

    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    using (StringReader sr = new StringReader(xml)) 
     using (XmlReader books = XmlReader.Create(sr, settings)) 
      return (T)serializer.Deserialize(books); 
} 
4

Por razones de extensibilidad, XmlSerializer es muy indulgente cuando se trata de deserialización; cosas como [DefaultValue], ShouldSerialize{Foo} y {Foo}Specified son principalmente utilizarse durante serialización (con la excepción de {Foo}Specified, que se establece durante la deserialización así como consulta durante la serialización).

Como tal; no hay una manera fácil de hacerlo, a menos que implemente IXmlSerializable y hágalo usted mismo. damagednoob muestra una opción xsd, que también es una opción.

+1

DefaultValue tiene al menos un efecto importante durante la deserialización. Si el elemento está vacío, sin DefaultValue puede haber un error de análisis. Sin embargo, con él, el [código generado] (http://msdn.microsoft.com/en-us/library/aa302290.aspx) omitirá el elemento vacío. –

Cuestiones relacionadas