Question

J'ai vu pas mal d'articles sur les modifications apportées à .NET 3.5 SP1, mais je suis tombé sur un article dont je n'ai pas encore vu la documentation d'hier.J'avais du code qui fonctionnait très bien sur ma machine, à partir de VS, de la ligne de commande msbuild, tout, mais il a échoué sur le serveur de build (exécutant .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; }
}

Dans SP1, le code ci-dessus fonctionne très bien.Dans RTM, vous obtenez une InvalidOperationException :

Impossible de générer une classe temporaire (résultat=1).erreur CS0200 :La propriété ou l'indexeur « ConsoleApplication2.Foo.Bar » ne peut pas être attribué : il est en lecture seule.

Bien sûr, tout ce qui est nécessaire pour le faire fonctionner sous RTM est d'ajouter [XmlIgnore] à la propriété Bar.

Mon Google Fu n'est apparemment pas en mesure de trouver de la documentation sur ce type de changements.Existe-t-il une liste de modifications quelque part qui répertorie ce changement (et des changements similaires sous le capot qui pourraient surgir et crier « je vous ai eu ») ?Est-ce un bug ou une fonctionnalité?

MODIFIER:Dans le SP1, si j'ajoutais un <Bar /> élément, ou définissez [XmlElement] pour la propriété Bar, il ne sera pas désérialisé.Il n'échoue pas avant le SP1 lorsqu'il tente de désérialiser : il lève une exception lorsque XmlSerializer est construit.

Cela me fait pencher davantage pour qu'il s'agisse d'un bug, surtout si je définis un attribut [XmlElement] pour Foo.Bar.S'il est incapable de faire ce que je lui demande, il devrait lever une exception au lieu d'ignorer silencieusement Foo.Bar.D'autres combinaisons/paramètres non valides d'attributs de sérialisation XML entraînent une exception.

MODIFIER:Merci, TonyB, je ne savais pas comment définir l'emplacement des fichiers temporaires.Pour ceux qui rencontreront des problèmes similaires à l’avenir, vous aurez besoin d’un indicateur de configuration supplémentaire :

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

Même en définissant un attribut [XmlElement] sur la propriété Bar, aucune mention n'en a été faite dans l'assembly de sérialisation généré, ce qui place assez clairement cela dans le domaine d'une erreur avalée silencieusement (c'est-à-dire un bug).Soit cela, soit les concepteurs ont décidé que [XmlIgnore] n'était plus nécessaire pour les propriétés qui ne peuvent pas être définies - et vous vous attendez à le voir dans les notes de version, modifier les listes, ou la Documentation XmlIgnoreAttribute.

Était-ce utile?

La solution

Dans SP1, la propriété foo.Bar est-elle correctement désérialisée ?

Dans la version antérieure au SP1, vous ne pouviez pas désérialiser l'objet car la méthode set de la propriété Bar est privée et XmlSerializer n'a donc aucun moyen de définir cette valeur.Je ne sais pas comment le SP1 y parvient.

Vous pouvez essayer de l'ajouter à votre web.config/app.config

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

Cela placera la classe générée par XmlSerializer dans c:\foo afin que vous puissiez voir ce qu'elle fait dans SP1 vs RTM

Autres conseils

J'aime plutôt ce nouveau (?) comportement car le document XML ne contient aucune mention de Bar, donc le désérialiseur ne devrait même pas tenter de le définir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top