Utilisez l’atsortingbut XmlInclude ou SoapInclude pour spécifier les types qui ne sont pas connus de manière statique

J’ai un problème très étrange lorsque je travaille avec XmlSerializer de .NET.

Prenez les exemples de classes suivants:

 public class Order { public PaymentCollection Payments { get; set; } //everything else is serializable (including other collections of non-abstract types) } public class PaymentCollection : Collection { } public abstract class Payment { //abstract methods } public class BankPayment : Payment { //method implementations } 

AFAIK, il existe trois méthodes différentes pour résoudre le problème InvalidOperationException causé par le sérialiseur qui ne connaît pas les types de Payment dérivés.

1. Ajout de XmlInclude à la définition de la classe de Payment :

Ce n’est pas possible car toutes les classes sont incluses en tant que références externes sur lesquelles je n’ai aucun contrôle.

2. Passer les types des types dérivés lors de la création de l’instance XmlSerializer

Ça ne marche pas

3. Définition de XmlAtsortingbuteOverrides pour la propriété target afin de remplacer la sérialisation par défaut de la propriété (comme expliqué dans cette publication SO )

Ne fonctionne pas non plus (l’initialisation de XmlAtsortingbuteOverrides suit).

 Type bankPayment = typeof(BankPayment); XmlAtsortingbutes atsortingbutes = new XmlAtsortingbutes(); atsortingbutes.XmlElements.Add(new XmlElementAtsortingbute(bankPayment.Name, bankPayment)); XmlAtsortingbuteOverrides overrides = new XmlAtsortingbuteOverrides(); overrides.Add(typeof(Order), "Payments", atsortingbutes); 

Le constructeur XmlSerializer approprié serait alors utilisé.

Remarque: par ne fonctionne pas, je veux dire que BankPayment ( BankPayment n’était pas prévu … ) est BankPayment .

Quelqu’un peut-il éclairer le sujet? Comment pourrait-on aller et déboguer le problème plus loin?

    Cela a fonctionné pour moi:

     [XmlInclude(typeof(BankPayment))] [Serializable] public abstract class Payment { } [Serializable] public class BankPayment : Payment {} [Serializable] public class Payments : List{} XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)}); 

    Je viens de résoudre le problème. Après avoir creusé un peu plus longtemps, j’ai trouvé ce post SO qui couvre exactement la même situation. Cela m’a mis sur la bonne voie.

    Fondamentalement, le XmlSerializer doit connaître l’espace de noms par défaut si les classes dérivées sont incluses en tant que types supplémentaires. La raison exacte pour laquelle cela doit arriver est encore inconnue, mais la sérialisation fonctionne toujours.