Pregunta

He visto bastantes publicaciones sobre cambios en .NET 3.5 SP1, pero ayer me topé con una de la que todavía no he visto la documentación.Tenía el código funcionando bien en mi máquina, desde VS, línea de comando msbuild, todo, pero falló en el servidor de compilación (ejecutando .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; }
}

En SP1, el código anterior funciona bien.En RTM, obtienes una InvalidOperationException:

No se puede generar una clase temporal (resultado=1).error CS0200:No se puede asignar la propiedad o el indexador 'ConsoleApplication2.Foo.Bar'; es de solo lectura

Por supuesto, todo lo que se necesita para ejecutarlo en RTM es agregar [XmlIgnore] a la propiedad Bar.

Aparentemente, mi Google Fu no está preparado para encontrar documentación de este tipo de cambios.¿Hay una lista de cambios en algún lugar que enumere este cambio (y cambios ocultos similares que podrían saltar y gritar "te tengo")?¿Es esto un error o una característica?

EDITAR:En SP1, si agregué un <Bar /> elemento, o establezca [XmlElement] para la propiedad Bar, no se deserializará.No falla antes del SP1 cuando intenta deserializar; genera una excepción cuando se construye 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, debería generar una excepción en lugar de ignorar silenciosamente Foo.Bar.Otras combinaciones/configuraciones no válidas de atributos de serialización XML dan como resultado una excepción.

EDITAR:Gracias, TonyB, no sabía cómo configurar la ubicación de los archivos temporales.Para aquellos que se encuentren con problemas similares en el futuro, necesitarán un indicador 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 la configuración de un atributo [XmlElement] en la propiedad Bar, no se hizo ninguna mención al respecto en el ensamblado de serialización generado, lo que coloca esto con bastante firmeza en el ámbito de un error que se traga silenciosamente (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 se pueden configurar, y es de esperar ver eso en las notas de la versión. listas de cambios, o el Documentación XmlIgnoreAttribute.

¿Fue útil?

Solución

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

En la versión anterior al SP1, no podría deserializar el objeto porque el método set de la propiedad Bar es privado, por lo que XmlSerializer no tiene forma de establecer ese valor.No estoy seguro de cómo lo está logrando SP1.

Podrías intentar agregar esto a tu web.config/app.config

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

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

Otros consejos

Me gusta bastante este nuevo (?) comportamiento porque el documento XML no menciona Bar, por lo que el deserializador ni siquiera debería intentar configurarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top