Pergunta

Já vi algumas postagens sobre mudanças no .NET 3.5 SP1, mas me deparei com uma cuja documentação ainda não vi ontem.Eu tinha o código funcionando bem na minha máquina, do VS, linha de comando msbuild, tudo, mas falhou no servidor de compilação (executando .NET 3.5 RTM).

[XmlRoot("foo")]
public class Foo
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Foo));

        string xml = @"<foo name='ack' />";
        using (StringReader sr = new StringReader(xml))
        {
            Foo foo = serializer.Deserialize(sr) as Foo;
        }
    }

    [XmlAttribute("name")]
    public string Name { get; set; }

    public Foo Bar { get; private set; }
}

No SP1, o código acima funciona perfeitamente.No RTM, você obtém uma InvalidOperationException:

Não foi possível gerar uma classe temporária (resultado=1).erro CS0200:A propriedade ou indexador 'ConsoleApplication2.Foo.Bar' não pode ser atribuído - é somente leitura

Claro, tudo o que é necessário para executá-lo em RTM é adicionar [XmlIgnore] à propriedade Bar.

Aparentemente, meu Google Fu não está à altura de encontrar documentação sobre esses tipos de mudanças.Existe uma lista de alterações em algum lugar que liste essa alteração (e alterações ocultas semelhantes que podem pular e gritar "peguei")?isso é um erro ou uma característica?

EDITAR:No SP1, se eu adicionasse um <Bar /> elemento ou defina [XmlElement] para a propriedade Bar, ele não será desserializado.Ele não falha antes do SP1 quando tenta desserializar – ele gera uma exceção quando o XmlSerializer é construído.

Isso me faz pensar que é um bug, especialmente se eu definir um atributo [XmlElement] para Foo.Bar.Se não for capaz de fazer o que eu peço, ele deverá lançar uma exceção em vez de ignorar silenciosamente o Foo.Bar.Outras combinações/configurações inválidas de atributos de serialização XML resultam em uma exceção.

EDITAR:Obrigado, TonyB, eu não sabia como definir o local dos arquivos temporários.Para aqueles que encontrarem problemas semelhantes no futuro, você precisará de um sinalizador de configuração adicional:

<system.diagnostics>
  <switches>
    <add name="XmlSerialization.Compilation" value="1" />
  </switches>
</system.diagnostics>
<system.xml.serialization>
  <xmlSerializer tempFilesLocation="c:\\foo"/>
</system.xml.serialization>

Mesmo com a definição de um atributo [XmlElement] na propriedade Bar, nenhuma menção foi feita a ele no assembly de serialização gerado - o que coloca isso firmemente no reino de um erro engolido silenciosamente (também conhecido como bug).Ou isso ou os designers decidiram que [XmlIgnore] não é mais necessário para propriedades que não podem ser definidas - e você esperaria ver isso nas notas de lançamento, listas de alterações, ou o Documentação XmlIgnoreAttribute.

Foi útil?

Solução

No SP1 a propriedade foo.Bar é desserializada corretamente?

No pré-SP1 você não seria capaz de desserializar o objeto porque o método set da propriedade Bar é privado, então o XmlSerializer não tem como definir esse valor.Não tenho certeza de como o SP1 está conseguindo.

Você poderia tentar adicionar isso ao seu web.config/app.config

<system.xml.serialization> 
  <xmlSerializer tempFilesLocation="c:\\foo"/> 
</system.xml.serialization> 

Isso colocará a classe gerada pelo XmlSerializer em c:\foo para que você possa ver o que está fazendo no SP1 vs RTM

Outras dicas

Eu gosto bastante desse novo (?) comportamento porque o documento XML não contém nenhuma menção a Bar, portanto, o desserializador nem deveria tentar configurá-lo.

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