¿Puede XmlSerializer deserializarse en un Nullable < int > ;?
-
08-07-2019 - |
Pregunta
Quería deserializar un mensaje XML que contiene un elemento que se puede marcar nil = " true "
en una clase con una propiedad de tipo int?
. La única forma en que pude hacerlo funcionar fue escribir mi propio tipo NullableInt
que implementa IXmlSerializable
. ¿Hay una mejor manera de hacerlo?
Escribí el problema completo y la forma en que lo resolví en mi blog .
Solución
Creo que necesita prefijar nil = " true " con un espacio de nombres para que XmlSerializer se deserialice a nulo.
<?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"/>
Otros consejos
Mi solución es preprocesar los nodos, arreglando cualquier " nil " atributos:
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);
}
Combino esto con una búsqueda recursiva de nodos secundarios, de modo que para cualquier XmlNode (o XmlDocument), puedo emitir una sola llamada antes de la deserialización. Si desea mantener la estructura original en memoria sin modificar, trabaje con un Clon () del XmlNode.
La manera excepcionalmente perezosa de hacerlo. Es frágil por varias razones, pero mi XML es lo suficientemente simple como para garantizar una solución tan rápida y sucia.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");