IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Silverlight Discussion :

RIA Service et Serialisation


Sujet :

Silverlight

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 7
    Par défaut RIA Service et Serialisation
    Bonjour,

    J'ai commencé à développer une petite application Silverlight en utilisant la technologie RIA Services.

    Tout fonctionne bien. Je me suis inspiré des tuto de David Rousset et de Brad Addams.

    Pour aller un peu plus loin, j'ai voulu ajouter un bouton permettant de sérialiser mes objets (des Clients) dans un fichier XML. Le but est bien sur de proposer un bouton pour désérialiser par la suite.

    Pour une raison inconnue, ça ne fonctionne pas. J'ai une erreur de type :

    There was an error reflecting type 'System.Collections.Generic.List' 1 [SerialisationRIA.Web.Client]'. There was an error reflecting type 'SerialisationRIA.Web.Client'.
    Ma fonction qui permet de sérialiser fonctionnait parfaitement sur une autre application que j'avais développé (sans RIA Services).

    Quelqu'un a t'il déjà eu ce genre de problème ?

    Ma classe Client (très simple avec simplement 3 champs):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
     
    namespace SerialisationRIA.Web
    {
        public class Client
        {
            [Key]
            public string ClientID { get; set; }
     
            [Required(
                ErrorMessage = "Le Nom du Client est obligatoire")]
            public string Nom { get; set; }
     
            [RegularExpression("^(?:m|M|f|F)$",
                ErrorMessage = "Valeur invalide : inidquez m,M ou f,F")]
            public string Sexe { get; set; }
        }
    }
    Ma Classe ClientList :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
     
    namespace SerialisationRIA.Web
    {
        public class ClientList
        {
            List<Client> listClient = new List<Client>()
            {
                new Client() {ClientID="0001", Nom="George", Sexe="M"},
                new Client() {ClientID="0002", Nom="Alain", Sexe="M"},
                new Client() {ClientID="0003", Nom="Robert", Sexe="M"},
                new Client() {ClientID="0004", Nom="Mauricette", Sexe="F"},
            };
     
            public IEnumerable<Client> GetClients()
            {
                return listClient.ToArray();
            }
     
            public void Add(Client emp)
            {
                listClient.Add(emp);
            }
     
            public void Update(Client current, Client orginal)
            {
                if (listClient.Contains(orginal)) listClient.Remove(orginal);
                Add(current);
            }
        }
    }
    Ma Classe Domaine Service (ClientDomainService) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    namespace SerialisationRIA.Web
    {
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.ComponentModel.DataAnnotations;
        using System.Linq;
        using System.Web.Ria;
        using System.Web.Ria.Data;
        using System.Web.DomainServices;
        using System.Data;
     
        [EnableClientAccess()]
        public class ClientDomainService : DomainService
        {
            ClientList Context = new ClientList();
     
            public IQueryable<Client> GetAllClients()
            {
                return Context.GetClients().AsQueryable();
            }
     
            public IQueryable<Client> GetUnClient(string clientID)
            {
                return Context.GetClients().ToList()
                    .Where(cli => cli.ClientID == clientID).AsQueryable();
            }
     
            public void InsertClient(Client unClient)
            {
                Context.Add(unClient);
            }
     
            public void UpdateClient(Client monClient)
            {
                Context.Update(monClient, this.ChangeSet.GetOriginal(monClient));
            }
     
            public override void Submit(ChangeSet changeSet)
            {
                base.Submit(changeSet);
                //todo: Submit changes to the store.. (for example, save to a file, etc
            }
        }
    }
    Dans la code XAML de Home, j'ai un Domain Data Source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <riaControls:DomainDataSource x:Name="source"
                                                  AutoLoad="True"
                                                  QueryName="GetAllClientsQuery"
                                                  LoadSize="20">
                        <riaControls:DomainDataSource.DomainContext>
                            <domain:ClientDomainContext />
                        </riaControls:DomainDataSource.DomainContext>
                    </riaControls:DomainDataSource>
    Les données apparaissent bien dans la grille, tout est ok de ce côté.

    Dans le Code Behind de Home, je fais donc appel à une méthode qui sérialise :

    Appel de la méthode pour sérialiser quand on clique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    private void BtnSerialiser_Click(object sender, RoutedEventArgs e)
            {
                var context = source.DomainContext as ClientDomainContext;
                MessageBox.Show(context.Clients[0].Nom); // Test pour voir si les données apparaissent
                Util.SerialiserLst<Client>(context.Clients.ToList());
            }
    Méthode pour Sérialiser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public static void SerialiserLst<T>(List<T> monObjet)
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer(monObjet.GetType());
                    System.IO.StringWriter sw = new System.IO.StringWriter();
                    serializer.Serialize(sw, monObjet);
                    string monXml = sw.ToString();
     
                    SaveFileDialog sf = new SaveFileDialog();
                    sf.DefaultExt = "xml";
                    sf.Filter = "Xml files (*.xml)|*.xml";
                    if (sf.ShowDialog().Value)
                    {
                        Stream stream = sf.OpenFile();
                        StreamWriter textWriter = new StreamWriter(stream);
                        textWriter.Write(monXml);
                        textWriter.Close();
                        stream.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + " " + ex.InnerException.Message);
                }
            }
    Pour télécharger l'application complète (format RAR - 2.5Mo)

    http://www.filzup.com/download.php?id=E7B4F6A31

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    A mon avis, il faut que tu marques ta classe Client comme étant sérializable. Regarde le détail de l'exception pour avoir le message d'erreur exact.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 7
    Par défaut
    J'ai rajouté [Serializable()] devant ma classe mais ça n'a rien changé

    Pour le message d'erreur, j'ai réussi à récupérer ça comment info en plus :

    There was an error reflecting type 'System.Collections.Generic.List`1[SerialisationRIA.Web.Client]'.

    à System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
    à System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, RecursionLimiter limiter)
    à System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
    à System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
    à System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
    à System.Xml.Serialization.XmlSerializer..ctor(Type type)
    à SerialisationRIA.Util.SerialiserLst[T](List`1 monObjet)

  4. #4
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Tu n'as pas plus d'infos dans les InnerExceptions ?

  5. #5
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 7
    Par défaut
    Effectivement, il y a des infos complémentaires dans le InnerException.

    To be XML serializable, types which inherit from ICollection must have an implementation of Add(System.Web.Ria.Data.OperationError) at all levels of their inheritance hierarchy. System.Collections.ObjectModel.ReadOnlyCollection ' 1 [[System.Web.Ria.Data.OperationError, System.Windows.Ria, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] does not implement Add(System.Web.Ria.Data.OperationError).

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Plutot que ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public IEnumerable<Client> GetClients()
            {
                return listClient.ToArray();
            }

    Essaye:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public List<Client> Clients
    {
        get
        {
            return this.listClient;
        }
    }
    Ensuite, remplace:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public IQueryable<Client> GetAllClients()
            {
                return Context.GetClients().AsQueryable();
            }

    Par ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public IQueryable<Client> GetAllClients()
            {
                return Context.Clients.AsQueryable();
            }

    Et regarde si cela fonctionne mieux.

Discussions similaires

  1. Réponses: 6
    Dernier message: 01/11/2009, 08h20
  2. .Net RIA Services et les règles de Validations
    Par Steven62 dans le forum Silverlight
    Réponses: 4
    Dernier message: 26/08/2009, 15h08
  3. RIA Services LazyLoading
    Par Xeron dans le forum Silverlight
    Réponses: 1
    Dernier message: 25/08/2009, 17h19
  4. Silverlight 3, RIA Services - En Prévision..
    Par 3KyNoX dans le forum Silverlight
    Réponses: 4
    Dernier message: 17/07/2009, 13h49
  5. XMLParserexection dans DomaiDataSource (.NET Ria Service)
    Par bleuerouge dans le forum Silverlight
    Réponses: 1
    Dernier message: 22/06/2009, 03h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo