2012-03-30 14 views
10

que tengo una clase comoserialise bool? de error que refleja el tipo

[Serializable] 
    public class MyClass 
    { 
     [XmlAttribute] 
     public bool myBool { get; set; } 
    } 

Pero esto serializa el valor de la bool false cuando el atributo no está presente en el XML. Cuando el atributo no está en el xml, quiero que la propiedad sea nula.

Así que probé este

[Serializable] 
public class MyClass 
{ 
    [XmlAttribute] 
    public bool? myBool { get; set; } 
} 

Pero entonces los errores serializador

Type t = Type.GetType("Assembly.NameSpace.MyClass"); 
       XmlSerializer mySerializer = new XmlSerializer(t); //error "There was an error reflecting type" 

Por favor, dame un ejemplo de lo que puedo hacer esto. Sé que hay algunas preguntas relacionadas sobre SO, pero nada que muestre cómo superar el error de reflexión con un bool nullable. Gracias.

Respuesta

9

Es necesario utilizar el patrón de campo "* especificada" para controlar este (Consulte "Control de XML generado" en MSDN):

[Serializable] 
public class MyClass 
{ 
    [XmlAttribute] 
    public bool myBool { get; set; } 

    [XmlIgnore] 
    public bool myBoolSpecified; 
} 

La lógica se convierte ahora en:

  • Si !myBoolSpecified, entonces myBool es lógicamente null
  • más use el true o false de myBool
+0

@Aliostad: Agradezco los méritos de su enfoque, pero si la estructura XML no está abierta a modificaciones, no funcionará mientras que esta lo hará. – Jon

+0

esto se ve muy bien, pero parece que no funciona. ¿El '{} especificado' es un nombre mágico? ¿Necesito algo de lógica en el getter? – Jules

+0

@Jules: Sí, es un nombre mágico. Busque "El patrón se crea en forma de propertyNameSpecified" en la página vinculada. Si no funciona, muestra tu código actual. – Jon

1

El problema es que un tipo anulable debe definirse como un elemento (que es el predeterminado) y no como un atributo.

razón es cuando el valor es nulo, se puede representar como <mybool xs:nil="true"/> como tal no puede ser representado como atributo.

Tenga una mirada en este fragmento:

[Serializable] 
public class MyClass 
{ 
    // removed the attribute!!! 
    public bool? myBool { get; set; } 
} 

Y:

XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
var stream = new MemoryStream(); 
serializer.Serialize(stream, new MyClass(){myBool = null}); 
Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray())); 

Salida:

<?xml version="1.0"?> 
<MyClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.o 
rg/2001/XMLSchema-instance"> 
    <myBool xsi:nil="true" /> <!-- NOTE HERE !!! --> 
</MyClass> 
+0

Gracias, pero esto es atributo en el xml recibo así que no puedo controlar eso.¿Hay alguna forma de tener un atributo bool nulable? – Jules

+0

@Jules La respuesta de Jon es correcta. – Aliostad

2

un vistazo a this para obtener información sobre tratar con campos anulables y atributos XML. Hay un question similar aquí también. Básicamente, el serializador no puede manejar un campo de atributo XML definido como anulable, pero hay una solución alternativa.

Es decir, 2 propiedades, una que contiene el valor nulo (no XML almacenado) y la otra que se utiliza en la lectura/escritura (atributo XML almacenado como una cadena). Quizás esto sea lo que necesitas?

private bool? _myBool; 
[XmlIgnore] 
public bool? MyBool 
{ 
    get 
    { 
     return _myBool; 
    } 
    set 
    { 
     _myBool = value; 
    } 
} 

[XmlAttribute("MyBool")] 
public string MyBoolstring 
{ 
    get 
    { 
     return MyBool.HasValue 
     ? XmlConvert.ToString(MyBool.Value) 
     : string.Empty; 
    } 
    set 
    { 
     MyBool = 
     !string.IsNullOrEmpty(value) 
     ? XmlConvert.ToBoolean(value) 
     : (bool?)null; 
    } 
} 
2

Puede utilizar XmlElementAttribute.IsNullable:

[Serializable] 
public class MyClass 
{ 
    [XmlElement(IsNullable = true)] 
    public bool? myBool { get; set; } 
} 
+0

Eso solo es factible cuando puedes elegir serializar como un elemento, en lugar de un atributo –

Cuestiones relacionadas