2011-06-18 14 views
6

Estoy intentando generar un documento xml en un formato específico. Me gustaría omitir la serialización de una propiedad según el valor de la propiedad.Xml Serialization Dynamic Ignore

public class Parent 
{ 
    public Parent() 
    { 
     myChild = new Child(); 
     myChild2 = new Child() { Value = "Value" }; 
    } 
    public Child myChild { get; set; } 
    public Child myChild2 { get; set; } 
} 

public class Child 
{ 
    private bool _set; 
    public bool Set { get { return _set; } } 

    private string _value = "default"; 
    [System.Xml.Serialization.XmlText()] 
    public string Value 
    { 
     get { return _value; } 
     set { _value = value; _set = true; } 
    } 
} 

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent)); 
x.Serialize(Console.Out, new Parent()); 

Si Set es falsa, quiero toda la propiedad a no ser serializado, mi XML resultante debe ser

<Parent> 
    <myChild2>default</myChild2> 
</Parent> 

En lugar de

<Parent> 
    <myChild/> 
    <myChild2>default</myChild2> 
</Parent> 

¿Hay alguna manera de que puedo hacer esto limpiamente con IXmlSerializable o cualquier otra cosa?

Gracias!

Respuesta

6

Hay un patrón ShouldSerialize * (introducido por TypeDescriptor, pero reconocido por algunas otras áreas del código, como XmlSerializer):

public bool ShouldSerializemyChild() { 
    return myChild != null && myChild.Set; 
} 

Esto debería solucionar el problema.

Una opción más simple, sin embargo, es asignarle nulo.

+0

que tienen una gran cantidad de propiedades que son todos de tipo infantil, preferiría no tener la ShouldSerialize para cada uno. Podría establecer todas mis propiedades en nulo que no estén configuradas antes de serializar ... – TrevDev

+0

Publiqué una respuesta para establecer dinámicamente el valor en nulo a través de un método que se llamaría antes de la serialización. ¿Tuviste una idea más clara para asignar un valor nulo? – TrevDev

+0

@Thx no realmente ... –

0

Si "Mi hijo" está definido por la matriz, creo que puede hacer bien ...

public class Parent 
{ 
    public Parent() 
    { 
     myChild = new Child[]{ new Child(){Value = "Value"}}; 
     //myChild2 = new Child() { Value = "Value" }; 
    } 
    public Child[] myChild { get; set; } 
    //public Child myChild2 { get; set; } 
} 
0

Creo que esto podría funcionar, aunque migh tiene que overide el método Equals

[DefaultValue(new Child())] 
public Child myChild{ get; set; } 
+0

Los argumentos de los atributos tienen que ser una constante – TrevDev

0

Acabo de escribir este código por diversión y tal vez aprender algo en el proceso. Debe establecer que cualquier propiedad sea nula si esa propiedad contiene un método llamado Set que devuelve bool, y su valor actual es falso. Al establecer los valores en falso, debería resolver el problema del serializador. Cualquier sugerencia:

public static void RemoveUnsetObjects(object currentObject) 
{ 
    var type = currentObject.GetType(); 
    if (currentObject is IEnumerable) 
    { 
     IEnumerable list = (currentObject as IEnumerable); 
     foreach (object o in list) 
     { 
      RemoveUnsetObjects(o); 
     } 
    } 
    else 
    { 
     foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) 
     { 
      var propertyValue = p.GetValue(currentObject, null); 
      if (propertyValue == null) 
       continue; 
        var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool)); 
      if (setPropInfo != null) 
      { 
       var isSet = (bool)setPropInfo.GetValue(propertyValue, null); 
       if (!isSet) 
       { 
        p.SetValue(currentObject, null, null); 
       } 
      } 
      else 
      { 
       RemoveUnsetObjects(propertyValue); 
      } 
     } 
    } 
}