2011-04-29 16 views
13
public class Hat 
{ 
    [XmlTextAttribute] 
    public string Name { get; set; } 
    [XmlAttribute("Color")] 
    public string Color { get; set; } 
} 

var hat1 = new Hat {Name="Cool Hat", Color="Red"}; 
var hat2 = new Hat {Name="Funky Hat", Color=null}; 

Esto es lo que me pasa (aviso de falta de color atributo en Funky sombrero):Serialize propiedad de cadena como atributo, incluso si la cadena está vacía

<Hats> 
<Hat Color="Red">Cool Hat</Hat> 
<Hat>Funky Hat</Hat> 
</Hats> 

Esto es lo que quiero:

<Hats> 
<Hat Color="Red">Cool Hat</Hat> 
<Hat Color="">Funky Hat</Hat> 
</Hats> 

¿Cómo puedo forzar al serializador a crear un atributo vacío en vez de omitirlo?

EDIT:

Resulta que soy un idiota y creé un ejemplo que contenía un error, porque quería simplificar el código para el ejemplo.

Si el valor de color es "" (o String.Empty), en realidad es serializado como un atributo vacío. Sin embargo, realmente tenía un valor nulo, no una cadena vacía, por lo tanto, se dejó de lado.

Así el comportamiento que quería era en realidad ya el comportamiento del ejemplo que he creado.

Lo siento, muchachos!

+0

_ "Si el valor del color es ""(o String.Empty), en realidad es serializado como un atributo vacío Sin embargo, realmente. tenía un valor nulo, no una cadena vacía, por lo que se dejó fuera. "_ Wow no se dio cuenta de ese comportamiento antes. Punto interesante –

Respuesta

5

Intente utilizar List<Hat> como el contenedor. El uso de este:

var hats = new List<Hat> 
    { 
     new Hat { Name = "Cool Hat", Color = "Red" }, 
     new Hat { Name = "Funky Hat", Color = string.Empty } 
    }; 

using (var stream = new FileStream("test.txt", FileMode.Truncate)) 
{ 
    var serializer = new XmlSerializer(typeof(List<Hat>)); 
    serializer.Serialize(stream, hats); 
} 

me sale esto:

<?xml version="1.0"?> 
<ArrayOfHat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Hat Color="Red">Cool Hat</Hat> 
    <Hat Color="">Funky Hat</Hat> 
</ArrayOfHat> 
+1

Esto me puso en el camino correcto, ya que mi contenedor ya era una lista . – Kjensen

1

Usted podría intentar establecer la propiedad Specified true. Además, creo que se puede utilizar una ## propiedad especificado para controlar la serialización, así:

[XmlAttribute("Color")] 
public string Color { get; set; } 
[XmlIgnore] 
public bool ColorSpecified { get { return true; } } // will always serialize 

O puede serializar, siempre y cuando no es nulo:

[XmlIgnore] 
public bool ColorSpecified { get { return this.Color != null; } } 
+1

Esto no parece funcionar. Nada cambia en el XML serializado. Para que quede claro, se supone que funciona simplemente porque el serializador busca una propiedad bool llamada [propiedad] Especificada - en este caso ColorSpecified? – Kjensen

+0

@Kjensen: Sé que funciona para los elementos (y [propiedad] Especificada es algo incorporado y codificado en el serializador; consulte http://msdn.microsoft.com/en-us/library/bb402199(v = exchg.140) .aspx). Lo mismo puede no funcionar para los atributos. – mellamokb

1

Hay dos maneras puede hacer esto

Usted podría utilizar [XmlElement(IsNullable=true)], lo que obligará al valor nulo al ser reconocido.

También es posible usar String.Empty lugar de "". Esto se reconoce como una cadena vacía y no como un nulo.

+10

'string.Empty ==" "' – Andrey

+0

[XmlElement (Isnullable = true)] solo funciona en elementos, no atributos. – Kjensen

+0

Pruébalo. Ha pasado un tiempo, pero recuerdo que funcionó para mí antes. Hay una pequeña diferencia entre String.Empty y "". El primero en realidad no crea un objeto. –

Cuestiones relacionadas