2008-08-29 14 views
5

He visto bastantes publicaciones sobre cambios en .NET 3.5 SP1, pero tropecé con una que todavía no he visto la documentación de ayer. Tenía código funcionando bien en mi máquina, desde VS, línea de comandos msbuild, todo, pero falló en el servidor de compilación (ejecutando .NET 3.5 RTM).Cambios de XmlSerializer en .NET 3.5 SP1

[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; } 
} 

En SP1, el código anterior funciona correctamente. En RTM, obtiene una InvalidOperationException:

No se puede generar una clase temporal (resultado = 1). CS0200 de error: la propiedad o indizador ConsoleApplication2.Foo.Bar 'no se puede asignar a - que es de sólo lectura

Por supuesto, todo lo que se necesita para que funcione bajo RTM es la adición de [XmlIgnore] a la barra propiedad.

Mi Google Fu aparentemente no está a la altura de la documentación de este tipo de cambios. ¿Hay alguna lista de cambios en algún lugar que enumere este cambio (y cambios similares en el interior que podrían saltar y gritar "gotcha")? ¿Es esto un error o una característica?

EDITAR: En SP1, si he añadido un elemento <Bar />, o ajuste [XmlElement] para la propiedad de bar, que no conseguirá deserializado. No falla antes de SP1 cuando intenta deserializar: lanza una excepción cuando se construye el XmlSerializer.

Esto me hace inclinarme más hacia que sea un error, especialmente si configuro un atributo [XmlElement] para Foo.Bar. Si no puede hacer lo que le pido que haga, debería lanzar una excepción en lugar de ignorar silenciosamente a Foo.Bar. Otras combinaciones/configuraciones no válidas de atributos de serialización XML dan como resultado una excepción.

EDIT: Gracias, TonyB, no sabía sobre la configuración de la ubicación de los archivos temporales. Para aquellos que vienen a través de problemas similares en el futuro, es necesario una bandera de configuración adicional:

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

Incluso con el ajuste de un atributo [XmlElement] en la propiedad Bar, no se hizo mención de ella en el ensamblado de serialización generado --lo que con bastante firmeza pone esto en el reino de un error tragado en silencio (también conocido como un error). O eso o los diseñadores han decidido que [XmlIgnore] ya no es necesario para las propiedades que no pueden configurarse, y usted esperaría ver eso en las notas de la versión, change lists, o XmlIgnoreAttribute documentation.

Respuesta

4

En SP1, ¿la propiedad foo.Bar se deserializa correctamente?

En pre SP1 no sería posible deserializar el objeto porque el método de establecimiento de la propiedad Bar es privado, por lo que XmlSerializer no tiene una manera de establecer ese valor. No estoy seguro de cómo SP1 lo está logrando.

Usted podría intentar agregar esto a su web.config/app.config

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

Eso pondrá la clase generada por el XmlSerializer en c: \ foo para que pueda ver lo que está haciendo en el SP1 vs RTM

+1

Esto no parece solucionar el problema en .NET 4 – Levitikon

0

Me gusta más este comportamiento nuevo (?) Porque el documento XML no tiene ninguna mención de Bar en él, por lo que el deserializador ni siquiera debería intentar configurarlo.

Cuestiones relacionadas