CodeS-SourceS
Rechercher un code, un tuto, une réponse

Soap Serialiser générique et Liste<T>

Avril 2017


Description


Je me suis apercu que la serialisation de liste générique avec un SoapFormater n'était pas pris en charge.
J'ai donc cherché a détourné le problème.


Problème rencontré


public class AxSerialiser<T>
{
    public static void SoapSerialiseToFile(string _Path, T _Object)
    {
        try
        {
            FileStream _FileStream = new FileStream(_Path, FileMode.OpenOrCreate, FileAccess.Write);
            SoapFormatter soapFormatter = new SoapFormatter();
            soapFormatter.Serialize(_FileStream, _Object);
            _FileStream.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("Failed SoapSerialiseToFile.rnReason : " + e.Message, "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

Ceci utilisé avec un objet contenant une Liste<T> renvoie une erreur.
J'ai donc implémenté la classe suivante.

Solution


/// <summary>
/// Classe générique fournissant une System.Collections.Generic.List
/// et l'implementation de ISerializable permettant de la sérialiser a l'aide d'un SoapFormatter.
/// </summary>
/// <typeparam name="T">The type of elements in the list.</typeparam>
[Serializable]
public abstract class GenericListClassObject<T> : ISerializable
{
    /// <summary>
    /// La Liste fournie par notre classe
    /// </summary>
    List<T> _List = new List<T>();
    
    /// <summary>
    /// La propriété marquée comme "virtual".
    /// c'est pratique pour voir de quoi on parle dans la classe dérivée.
    /// </summary>
    public virtual List<T> List
    {
        get { return _List; }
        set { _List = value; }
    }
    
    /// <summary>
    /// Le constructeur
    /// </summary>
    public GenericListClassObject()
    {

    }
    
    #region Membres de ISerializable
    /// <summary>
    /// Le "déconstructeur" utilisé pour la sérialisation.
    /// </summary>
    /// <param name="info">Stores all the data needed to serialize or deserialize an object.</param>
    /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param>
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        ///On vas tout simplement transformer notre Liste de 'T' en un tableau de 'T'
        ///et l'ajouter au SerializationInfo.
        info.AddValue("_List", _List.ToArray(), typeof(T[]));
        Type t = this.GetType();
        info.AddValue("TypeObj", t);
    }

    /// <summary>
    /// Le constructeur Utilisé pour la désérialisation
    /// </summary>
    /// <param name="si">Stores all the data needed to serialize or deserialize an object.</param>
    /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param>
    public GenericListClassObject(SerializationInfo si, StreamingContext context)
    {
        ///On récupere notre tableau d'objets 'T' dans SerializationInfo.
        T[] tmp = (T[])si.GetValue("_List", typeof(T[]));
        ///On remet les elements du tableau dans notre Liste.
        _List = new List<T>((IEnumerable<T>) tmp);
    }

    #endregion
}

On peut donc utiliser une classe telle que celle ci:

/// </summary>
[Serializable]
public class Hotel : GenericListClassObject<Chambre>,ISerializable
{
    /// <summary>
    /// Champ 'nom', le nom de notre hotel
    /// </summary>
    string nom = "Hotel Bel air";
    
    /// <summary>
    /// Propriéte 'Nom'.
    /// </summary>
    public string Nom
    {
        get { return nom; }
        set { nom = value; }
    }
    
    /// <summary>
    /// Propriéte List, celle ci est fournie par notre classe 'GenericListClassObject'.
    /// </summary>
    public override List<Chambre> List
    {
        get {return base.List;}
        set {base.List = value;}
    }
    
    /// <summary>
    /// Le constructeur Utilisé pour la désérialisation
    /// </summary>
    /// <param name="si">Stores all the data needed to serialize or deserialize an object.</param>
    /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param>
    public Hotel(SerializationInfo si, StreamingContext context)
    {

    }
    
    /// <summary>
    /// Le constructeur.
    /// </summary>
    public Hotel()
    { }
}

Conclusion


Le tour est joué.

A voir également

Publié par cs_Axel123.
Ce document intitulé «  Soap Serialiser générique et Liste<T>  » issu de CodeS-SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Ajouter un commentaire

Commentaires

Donnez votre avis
Interface utilisateur multitâches
Tutoriel détaillé de WSSF Modeling Edition avec base de données SQL 2005