Désérialisation d’objects XML en interface

J’ai deux classes SccmAction et TicketAction qui implémentent toutes les deux l’interface IDelivery. Ces classes seront transmises dans une queue de traitement à partir de laquelle je souhaite simplement extraire le message et appliquer la méthode Deliver.

Il semble cependant que je ne puisse pas désérialiser sur une interface car une tentative d’ exception System.NotSupportedException est émise . D’après ce que j’ai recueilli, XMLSerializer requirejs un type concret pour la sérialisation. Dois-je alors créer une classe abstraite qui implémente IDelivery et en hérite de SccmAction et ArsAction? Ai-je raté quelque chose qui?

Éditer une clarification supplémentaire

J’ai peut-être un défaut de conception mais mon but est de retirer des messages d’une queue contenant ces objects. Mon intention était de faire en sorte que tous les objects sortant de cette queue implémentent l’interface en s’assurant que l’application traitant les objects ne fonctionne que sur la méthode Deliver. La mise en œuvre de chaque object de Deliver varierait.

Code à désérialiser

using (SqlConnection connection = new SqlConnection(ConnectionSsortingng)) { SqlCommand command = new SqlCommand(ReceiveSsortingng, connection); connection.Open(); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { byte[] sb = (byte[])reader["message_body"]; SccmAction sa = DeserializeObject(sb); IDelivery iD = DeserializeObject(sb); } reader.Close(); } public static T DeserializeObject(byte[] ba) { XmlSerializer xs = new XmlSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(ba); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); return (T)xs.Deserialize(memoryStream); } 

Classes et Interface

 [Serializable] public class SccmAction : IDelivery { public ssortingng MachineName { get; set; } public ssortingng CollectionName { get; set; } public ssortingng Action { get; set; } public DateTime EntryDateTime { get; set; } public SccmAction () { } public void Deliver() { throw new NotImplementedException(); } } [Serializable] public class ArsAction : IDelivery { public ssortingng MachineName { get; set; } public ssortingng CustomerName { get; set; } public ArsAction() { } public void Deliver() { throw new NotImplementedException(); } } public interface IDelivery { void Deliver(); } 

En termes simples, vous ne pouvez pas sérialiser une interface sans saleté. Mais pourquoi voulez-vous quand même sérialiser votre interface, elle ne détient aucun état. Il a seulement une déclaration pour une méthode.

Vous souhaiterez peut-être créer une méthode Serialize dans vos classes. Pour pouvoir se mettre en série individuellement, ils savent de quel type ils sont.

En outre, comment vous attendez-vous à ce que XmlSerializer se désérialise avec un type exact sans le fournir? Il ne peut pas simplement choisir quoi désérialiser pour …

Vous pouvez cependant changer cette ligne

 IDelivery iD = DeserializeObject(sb); 

pour ça

 IDelivery iD = DeserializeObject(sb); 

Si vous ne savez pas à quel type vous désérialisez initialement (ArsAction ou SccmAction), vous pouvez procéder de la sorte.

 public static IDelivery DeserializeFromSsortingng(ssortingng xml) { //replace this stream with whatever you are useing SsortingngReader strReader = new SsortingngReader(xml); XmlReader reader = new XmlTextReader(fs); //important to use XmlReader reader.MoveToContent(); //move to root Ssortingng className = reader.Name.Trim(); //read the class name //use the namespace IDelivery is located in className = "IDeliveryNamespace." + className; //get the type Type classType = Type.GetType(className); XmlSerializer serializer = new XmlSerializer(Type.GetType(className)); // Declare an object variable of the type to be deserialized. IDelivery i; // Use the Deserialize method to restore the object's state. i = (IDelivery)Convert.ChangeType(serializer.Deserialize(reader),classType); return i; } 

Bien entendu, cela suppose que votre nom de classe Serializable ne soit pas modifié. Cela signifie que la classe ArsAction est sérialisée dans les limites de ce que vous avez posté et, autant que je sache, c’est le cas.

Ce code est un peu sale, mais il devrait vous donner un sharepoint départ.