Can XmlSerializer desserializar em um Nullable ?
-
08-07-2019 - |
Pergunta
Eu queria desserializar uma mensagem XML contendo um elemento que pode ser marcado nil="true"
em uma classe com uma propriedade do tipo int?
. A única maneira que eu poderia obtê-lo para o trabalho era escrever meu próprio tipo NullableInt
que implementa IXmlSerializable
. Existe uma maneira melhor de fazer isso?
Eu escrevi o problema completo e da maneira que eu resolvi no meu blog .
Solução
Eu acho que você precisa prefixar o nil = "true" com um espaço de nomes para que XmlSerializer para deserialise como 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"/>
Outras dicas
Meu correção é para pré-processar os nós, fixando quaisquer atributos "nada":
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);
}
Eu Junte isso com uma pesquisa recursiva para nós filhos, de modo que para qualquer dado XmlNode (ou XmlDocument), eu posso emitir uma única chamada antes desserialização. Se você quiser manter o original estrutura em memória sem modificações, o trabalho com um Clone () do XmlNode.
A forma excepcionalmente preguiçoso para fazê-lo. É frágil para uma série de razões, mas o meu XML é simples o suficiente para justificar uma correção tão rápida e suja.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");