Pergunta

Eu tenho uma propriedade definida como:

[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
 XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }

Se List<> Delete não tiver itens

<delete />

é emitido.Se List<> Delete estiver definido como nulo

<delete xsi:nil="true" />

é emitido.Existe uma maneira de usar atributos para fazer com que o elemento delete não seja emitido se a coleção não tiver itens?

Greg - Perfeito, obrigado, eu nem li a documentação do IsNullable, apenas presumi que estava sinalizando como não obrigatório.

Rob Cooper - Eu estava tentando evitar ISerializable, mas a sugestão do Greg funciona.Encontrei o problema que você descreveu em (1), quebrei um monte de código apenas retornando nulo se a coleção tivesse comprimento zero.Para contornar isso, criei uma classe EventsBuilder (a classe que estou serializando é chamada Events) que gerenciava todo o tempo de vida/criação dos objetos subjacentes da classe Events que cospe nossas classes Events para serialização.

Foi útil?

Solução

Se você definir IsNullable=false ou apenas removê-lo (é falso por padrão), o elemento "delete" não será emitido.Isso funcionará apenas se a coleção for igual a nula.

Meu palpite é que há uma confusão entre "anulidade" em termos de .NET e aquela relacionada a elementos anuláveis ​​em XML - aqueles que são marcados pelo atributo xml:nil.A propriedade XmlArrayAttribute.IsNullable controla o último.

Outras dicas

Eu tive o mesmo problema em que não queria que um elemento fosse gerado se o campo estivesse vazio ou 0.O XML gerado não pôde usar xsi:null="true" (por design).

Eu li em algum lugar que se você incluir uma propriedade do tipo bool com o mesmo nome do campo que deseja controlar, mas anexada com 'Especificado', o XMLSerializer verificará o valor de retorno desta propriedade para determinar se o campo correspondente deve ser incluído.

Para conseguir isso sem implementar IXMLSerializer:

public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
 get
 {
   bool isRendered = false;
   if (Delete != null)
   {
     isRendered = (Delete.Count > 0);
   } 

   return isRendered;
 }
 set
 {
 }
}

Em primeiro lugar, eu diria que pergunte a si mesmo "O que é serialização?".

O XMLSerializador está fazendo exatamente o que deveria estar fazendo, persistindo o estado atual do objeto em XML.Agora, não sei por que o comportamento atual não é "certo" para você, pois se você inicializou a Lista, então ela é inicializado.

Acho que você tem três opções aqui:

  1. Adicione código ao Getter para retornar nulo se a coleção tiver 0 itens.Isso pode atrapalhar outro código que você possui.
  2. Implementar o IXmlSerializável interface e faça todo o trabalho sozinho.
  3. Se este for um processo comum, você pode querer dar uma olhada na minha pergunta "Serialização XML e tipos herdados" - Sim, eu sei que trata de outro problema, mas mostra como criar uma classe de serialização intermediária genérica que pode então ser "aparafusada" para permitir que um processo de serilização seja encapsulado.Você poderia criar uma classe semelhante para lidar com a substituição do processo padrão para coleções de itens nulos/zero.

Eu espero que isso ajude.

Você sempre pode implementar IXmlSerializer e executar a serialização manualmente.

Ver http://www.codeproject.com/KB/cs/IXmlSerializable.aspx Por exemplo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top