XmlSerializer può deserializzare in un Nullable < int > ;?
-
08-07-2019 - |
Domanda
Volevo deserializzare un messaggio XML contenente un elemento che può essere contrassegnato nil = " true "
in una classe con una proprietà di tipo int?
. L'unico modo per farlo funzionare era scrivere il mio tipo NullableInt
che implementa IXmlSerializable
. C'è un modo migliore per farlo?
Ho scritto il problema completo e il modo in cui l'ho risolto sul mio blog .
Soluzione
Penso che devi aggiungere il prefisso nil = " true " con uno spazio dei nomi per consentire a XmlSerializer di deserializzare su null.
<?xml version="1.0" encoding="UTF-8"?>
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array">
<entity>
<id xsi:type="integer">1</id>
<name>Foo</name>
<parent-id xsi:type="integer" xsi:nil="true"/>
Altri suggerimenti
La mia correzione è di pre-elaborare i nodi, riparando qualsiasi "quot" zero " attributi:
public static void FixNilAttributeName(this XmlNode @this)
{
XmlAttribute nilAttribute = @this.Attributes["nil"];
if (nilAttribute == null)
{
return;
}
XmlAttribute newNil = @this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance");
newNil.Value = nilAttribute.Value;
@this.Attributes.Remove(nilAttribute);
@this.Attributes.Append(newNil);
}
Unisco questo con una ricerca ricorsiva per nodi figlio, in modo che per ogni dato XmlNode (o XmlDocument), possa emettere una singola chiamata prima della deserializzazione. Se vuoi mantenere la struttura originale in memoria non modificata, lavora con un Clone () di XmlNode.
Il modo eccezionalmente pigro per farlo. È fragile per una serie di motivi, ma il mio XML è abbastanza semplice da giustificare una soluzione così rapida e sporca.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");