2012-03-30 10 views
10

Ho una classe comeserializza bool? errore di tipo riflettente

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

Ma questo serializza il valore del bool false quando l'attributo non è presente nel XML. Quando l'attributo non è nell'xml, voglio che la proprietà sia null.

Così ho provato questo

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

Ma poi gli errori serializzatore

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

Per favore mi dia un esempio di posso fare questo. So che ci sono alcune domande correlate su SO ma nulla che mostri come superare l'errore di riflessione con un bool nullable. Grazie.

risposta

9

È necessario utilizzare il modello di campo "* specificato" per controllare questo (vedi "Controllo dell'XML generato" su MSDN):

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

    [XmlIgnore] 
    public bool myBoolSpecified; 
} 

La logica diventa ora:

  • Se !myBoolSpecified, quindi myBool è logicamente null
  • Else usare il true o false di myBool
+0

@Aliostad: Apprezzo i pregi del tuo approccio, ma se la struttura XML non è aperta alle modifiche, non funzionerà mentre lo farà. – Jon

+0

sembra ottimo ma non sembra funzionare. "{} Specificato" è un nome magico? ho bisogno di un po 'di logica nel getter? – Jules

+0

@Jules: Sì, è un nome magico. Cerca "Il modello è creato sotto forma di propertyNameSpecified" nella pagina collegata. Se non funziona, mostra il tuo codice attuale. – Jon

1

Il problema è che un tipo nullable deve essere definito come un elemento (che è l'impostazione predefinita) e non l'attributo.

ragione è quando il valore è nullo, esso può essere rappresentato come <mybool xs:nil="true"/> come tale non può essere rappresentato come attributo.

Date un'occhiata a questo frammento:

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

E:

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

uscita:

<?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

Grazie, ma questo è attributo nel xml che ricevo così non posso controllare quello.C'è un modo per avere un attributo bool nullable? – Jules

+0

@Jules La risposta di Jon è corretta. – Aliostad

2

Date un'occhiata al this per informazioni riguardanti occuparsi di campi nullable e attributi XML. Anche qui c'è un simile question. Fondamentalmente, il serializzatore non può gestire un campo di attributo XML definito come annullabile, ma c'è un work-around.

I.e 2 proprietà, una che contiene il nullable (non XML memorizzato) e l'altra che viene utilizzata nella lettura/scrittura (attributo XML memorizzato come stringa). Forse questo potrebbe essere quello che ti serve?

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

È possibile utilizzare XmlElementAttribute.IsNullable:

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

Ciò è possibile solo quando è possibile scegliere di serializzare come elemento invece di un attributo –

Problemi correlati