Pregunta

Tengo una propiedad definida como:

[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
 XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }

Si la Lista<> Eliminar no tiene elementos

<delete />

se emite.Si Lista<> Eliminar está establecido en nulo

<delete xsi:nil="true" />

se emite.¿Hay alguna forma de utilizar atributos para que el elemento de eliminación no se emita si la colección no tiene elementos?

Greg - Perfecto gracias, ni siquiera leí la documentación de IsNullable, simplemente supuse que indicaba que no era necesaria.

Rob Cooper - Estaba intentando evitar ISerializable, pero la sugerencia de Greg funciona.Me encontré con el problema que usted describió en (1), rompí un montón de código simplemente devolviendo nulo si la colección tenía una longitud cero.Para solucionar esto, creé una clase EventsBuilder (la clase que estoy serializando se llama Eventos) que administra toda la vida útil/creación de los objetos subyacentes de la clase Eventos que escupe nuestras clases de Eventos para su serialización.

¿Fue útil?

Solución

Si configura IsNullable=false o simplemente lo elimina (es falso de forma predeterminada), entonces el elemento "eliminar" no se emitirá.Esto funcionará sólo si la colección es igual a nula.

Mi conjetura es que existe una confusión entre la "capacidad de anular" en términos de .NET y la relacionada con elementos que aceptan valores NULL en XML, aquellos que están marcados con el atributo xml:nil.La propiedad XmlArrayAttribute.IsNullable controla este último.

Otros consejos

Tuve el mismo problema en el que no quería que se generara un elemento si el campo estaba vacío o era 0.El XML generado no pudo usar xsi:null="true" (por diseño).

Leí en alguna parte que si incluye una propiedad de tipo bool con el mismo nombre que el campo que desea controlar pero al que se le agrega 'Especificado', XMLSerializer verificará el valor de retorno de esta propiedad para determinar si el campo correspondiente debe ser incluido.

Para lograr esto sin implementar IXMLSerializer:

public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
 get
 {
   bool isRendered = false;
   if (Delete != null)
   {
     isRendered = (Delete.Count > 0);
   } 

   return isRendered;
 }
 set
 {
 }
}

En primer lugar, diría que te preguntes "¿Qué es la serialización?".

El XmlSerializador está haciendo exactamente lo que se supone que debe hacer, persistiendo el estado actual del objeto en XML.Ahora, no estoy seguro de por qué el comportamiento actual no es "correcto" para usted, ya que si ha inicializado la Lista, entonces es inicializado.

Creo que tienes tres opciones aquí:

  1. Agregue código al Getter para devolver nulo si la colección tiene 0 elementos.Sin embargo, esto puede estropear otro código que tengas.
  2. Implementar el IXmlSerializable interfaz y haga todo el trabajo usted mismo.
  3. Si este es un proceso común, es posible que desee consultar mi pregunta "Serialización XML y tipos heredados" - Sí, sé que trata otro tema, pero le muestra cómo crear una clase de serialización intermedia genérica que luego se puede "añadir" para permitir que se encapsule un proceso de serilización.Podría crear una clase similar para lidiar con la anulación del proceso predeterminado para colecciones de elementos nulos/cero.

Espero que esto ayude.

Siempre puedes implementar IXmlSerializer y realizar la serialización manualmente.

Ver http://www.codeproject.com/KB/cs/IXmlSerializable.aspx para un ejemplo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top