XmlSerializer – Il y avait une erreur de type reflétant

En utilisant C # .NET 2.0, j’ai une classe de données composite qui possède l’atsortingbut [Serializable] . Je crée une classe XMLSerializer et la transmet au constructeur:

 XmlSerializer serializer = new XmlSerializer(typeof(DataClass)); 

Je reçois une exception en disant:

Il y avait un type reflétant l’erreur.

Dans la classe de données, il y a un autre object composite. Cela doit-il également avoir l’atsortingbut [Serializable] ou, en l’ayant sur l’object supérieur, l’applique-t-il récursivement à tous les objects à l’intérieur?

Examinez l’exception interne que vous obtenez. Il vous indiquera quel champ / propriété il a du mal à sérialiser.

Vous pouvez exclure des champs / propriétés de la sérialisation XML en les décorant avec l’atsortingbut [XmlIgnore] .

Je ne pense pas que XmlSerializer utilise l’atsortingbut [Serializable] , alors je doute que ce soit le problème.

N’oubliez pas que les classes sérialisées doivent avoir des constructeurs par défaut (c’est-à-dire sans paramètre). Si vous n’avez aucun constructeur, c’est bien; mais si vous avez un constructeur avec un paramètre, vous devrez également en append un par défaut.

J’ai eu un problème similaire, et il s’est avéré que le sérialiseur ne pouvait pas distinguer deux classes que j’avais avec le même nom (l’une était une sous-classe de l’autre). L’exception interne ressemblait à ceci:

‘Types BaseNamespace.Class1’ et ‘BaseNamespace.SubNamespace.Class1’ utilisent tous deux le nom de type XML, ‘Class1’, de namespace ”. Utilisez les atsortingbuts XML pour spécifier un nom XML et / ou un espace de noms unique pour le type.

Où BaseNamespace.SubNamespace.Class1 est une sous-classe de BaseNamespace.Class1.

Ce que je devais faire était d’append un atsortingbut à l’une des classes (j’ai ajouté à la classe de base):

 [XmlType("BaseNamespace.Class1")] 

Remarque: Si vous avez plus de couches de classes, vous devez également leur append un atsortingbut.

XmlSerializer également que XmlSerializer ne peut pas sérialiser les propriétés abstraites. Voir ma question ici (à laquelle j’ai ajouté le code de la solution).

Sérialisation XML et types hérités

Les raisons les plus courantes par moi:

  - the object being serialized has no parameterless constructor - the object contains Dictionary - the object has some public Interface members 

Tous les objects du graphe de sérialisation doivent être sérialisables.

Puisque XMLSerializer est une XMLSerializer , vérifiez ces liens si vous souhaitez déboguer davantage dans le processus de sérialisation.

Modification de l’emplacement des assemblages temporaires par XmlSerializer

COMMENT FAIRE: Déboguer dans un assemblage généré par .NET XmlSerializer

Si vous avez besoin de gérer des atsortingbuts spécifiques (par exemple, Dictionary ou toute classe), vous pouvez implémenter l’interface IXmlSerialiable , ce qui vous permettra plus de liberté au prix d’un codage plus détaillé .

 public class NetService : IXmlSerializable { #region Data public ssortingng Identifier = Ssortingng.Empty; public ssortingng Name = Ssortingng.Empty; public IPAddress Address = IPAddress.None; public int Port = 7777; #endregion #region IXmlSerializable Implementation public XmlSchema GetSchema() { return (null); } public void ReadXml(XmlReader reader) { // Atsortingbutes Identifier = reader[XML_IDENTIFIER]; if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false) throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT); if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false) throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR); } public void WriteXml(XmlWriter writer) { // Atsortingbutes writer.WriteAtsortingbuteSsortingng(XML_IDENTIFIER, Identifier); writer.WriteAtsortingbuteSsortingng(XML_NETWORK_ADDR, Address.ToSsortingng()); writer.WriteAtsortingbuteSsortingng(XML_NETWORK_PORT, Port.ToSsortingng()); } private const ssortingng XML_IDENTIFIER = "Id"; private const ssortingng XML_NETWORK_ADDR = "Address"; private const ssortingng XML_NETWORK_PORT = "Port"; #endregion } 

Il existe un article intéressant, qui montre une manière élégante d’implémenter un moyen sophistiqué d’extension de XmlSerializer.


L’article dit:

IXmlSerializable est couvert dans la documentation officielle, mais la documentation indique qu’il n’est pas destiné à un usage public et ne fournit aucune information supplémentaire. Cela indique que l’équipe de développement souhaitait se réserver le droit de modifier, désactiver ou même supprimer complètement ce crochet d’extensibilité. Cependant, tant que vous êtes prêt à accepter cette incertitude et à faire face à d’éventuels changements à l’avenir, il n’y a aucune raison que vous ne puissiez pas en profiter.

Parce que cela, je suggère de mettre en œuvre vos propres classes IXmlSerializable , afin d’éviter des implémentations trop compliquées.

… il pourrait être simple d’implémenter notre classe XmlSerializer personnalisée en utilisant la reflection.

J’ai découvert que la classe Dictionary dans .Net 2.0 n’est pas sérialisable à l’aide de XML, mais se sérialise bien lorsque la sérialisation binary est utilisée.

J’ai trouvé un travail ici .

Je l’ai récemment obtenu dans une classe partielle de référence Web lors de l’ajout d’une nouvelle propriété. La classe générée automatiquement ajoutait les atsortingbuts suivants.

  [System.Xml.Serialization.XmlElementAtsortingbute(Order = XX)] 

J’avais besoin d’append un atsortingbut similaire avec un ordre plus élevé que le dernier dans la séquence générée automatiquement, et cela a été corrigé pour moi.

Je pensais aussi que l’atsortingbut Serializable devait être sur l’object mais à moins que je ne sois un noob complet (je suis au milieu d’une session de codage tard dans la nuit), les travaux suivants du SnippetComstackr :

 using System; using System.IO; using System.Xml; using System.Collections.Generic; using System.Xml.Serialization; public class Inner { private ssortingng _AnotherSsortingngProperty; public ssortingng AnotherSsortingngProperty { get { return _AnotherSsortingngProperty; } set { _AnotherSsortingngProperty = value; } } } public class DataClass { private ssortingng _SsortingngProperty; public ssortingng SsortingngProperty { get { return _SsortingngProperty; } set{ _SsortingngProperty = value; } } private Inner _InnerObject; public Inner InnerObject { get { return _InnerObject; } set { _InnerObject = value; } } } public class MyClass { public static void Main() { try { XmlSerializer serializer = new XmlSerializer(typeof(DataClass)); TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml"); DataClass clazz = new DataClass(); Inner inner = new Inner(); inner.AnotherSsortingngProperty = "Foo2"; clazz.InnerObject = inner; clazz.SsortingngProperty = "foo"; serializer.Serialize(writer, clazz); } finally { Console.Write("Press any key to continue..."); Console.ReadKey(); } } } 

J’imagine que le XmlSerializer utilise la reflection sur les propriétés publiques.

J’ai eu une situation où l’ordre était le même pour deux éléments d’affilée

 [System.Xml.Serialization.XmlElementAtsortingbute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")] 

…. du code …

 [System.Xml.Serialization.XmlElementAtsortingbute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")] 

Lorsque j’ai modifié le code pour incrémenter la commande de un pour chaque nouvelle propriété de la classe, l’erreur a disparu.

Je viens de recevoir la même erreur et j’ai découvert qu’une propriété de type IEnumerable était le problème. Il semble que IEnumerable ne peut pas être sérialisé directement.

Notez également que vous ne pouvez pas sérialiser les contrôles de l’interface utilisateur et que tout object que vous souhaitez transmettre au Presse-papiers doit être sérialisable, sinon il ne peut pas être transmis à d’autres processus.

J’ai utilisé la classe NetDataSerialiser pour sérialiser mes classes de domaine. Classe NetDataContractSerializer .

Les classes de domaine sont partagées entre le client et le serveur.

[System.Xml.Serialization.XmlElementAtsortingbute (“strFieldName”, Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

//Ou

[XmlIgnore] ssortingng [] strFielsName {get; set;}

J’ai eu le même problème et dans mon cas, l’object avait un ReadOnlyCollection. Une collection doit implémenter la méthode Add pour être sérialisable.