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 :

[SL+WCF] Erreur de contrat => Type inconnu.


Sujet :

Silverlight

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 35
    Par défaut [SL+WCF] Erreur de contrat => Type inconnu.
    Bonjour à vous,

    J'arrive aujourd'hui encore avec un problème que je ne saurais pas trop expliquer.

    J'ai une application Silverlight qui communique avec un service WCF via un binding personnalisé utilisant pollingDuplexElement.

    Je test à chaque "grosse étape" si ce que je fais fonctionne...Et jusque là, je n'avais aucun problème de communication.

    Aujourd'hui, j'ai une erreur, côté Silverlight, de type DataContractFaultException (ou du même style) qui me dit (en gros) qu'il ne connait pas les types représentés par le message entrant et qu'il faudrait que je spécifie les types en question avec KnownTypeAttribute au dessus de mon contrat de données racine.

    Chose "amusante", l'attribut "KnownType" est déjà présent . J'utilise cet attribut en relation avec une méthode publique et statique, chargée de me retourner tous les types héritant de ma classe de base dans un assembly donné.

    En plaçant quelques points d'arrêt, je me rend bien compte que côté serveur, la méthode de listing des types enfant est appelée mais que côté Silverlight, il n'y a rien à faire!!!

    Bref, je ne sais plus quoi faire, ce Silverlight est en train de me rendre fou...

    Si vous avez une idée... Si vous avez besoin de plus d'informations, n'hésitez pas non plus.

    merci d'avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut,

    Un peu de code ferait du bien je pense

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 35
    Par défaut
    Ceci se trouve dans un projet "Framework .NET 4.0" :

    Déclaration de la classe de base :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
       [DataContract(IsReference = true)] 
       //[KnownType(typeof(ModelLayer.Implementations.UsersImplementations.Professional))]
       //[KnownType(typeof(ModelLayer.Implementations.UsersImplementations.User))]
    #if !SILVERLIGHT
        [Serializable]
    #endif
        [KnownType("ListChilds")]
        public abstract class SerializableModel : INotifyPropertyChanged
    Jusque là, cette technique ne permettait d'ajouter des types héritant de SerializableModel sans avoir à rajouter manuellement un "KnownType" au dessus de cette classe. Ce fut testé dans un projet WPF et Silverlight (sans liens) avec succès.
    Comme l'indiquent les commentaires, j'ai testé en spécifiant le type de modèle directement...Sans succès également.

    Code de la méthode ListChilds :
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    private static List<Type> _childs;
     
    #region ListChilds()
            /// <summary>
            /// Retourne la liste des types héritant de ModelBase
            /// </summary>
            /// <returns>Liste de type</returns>
            public static IEnumerable<Type> ListChilds()
            {
                if (_childs == null)
                {
                    _childs = new List<Type>();
                    Type modelType = typeof(ModelBase);
    #if SILVERLIGHT
                    System.Reflection.Assembly[] assemblies = new System.Reflection.Assembly[1];
                    foreach (System.Windows.AssemblyPart ap in System.Windows.Deployment.Current.Parts)
                    {
                        if (ap.Source.Contains("SilverlightModel"))
                        {
                            System.Windows.Resources.StreamResourceInfo sri = System.Windows.Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));
                            System.Windows.AssemblyPart part = new System.Windows.AssemblyPart();
                            assemblies[0] = part.Load(sri.Stream);
                            break;
                        }
                    }
    #else
                    System.Reflection.Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    #endif
                    foreach (System.Reflection.Assembly asm in assemblies)
                    {
                        String name = asm.FullName;
                        if (SerializableModel.CheckAssemblyName(name))
                        {
                            foreach (Type t in asm.GetTypes())
                            {
                                if (modelType.IsAssignableFrom(t))
                                {
                                    _childs.Add(t);
                                }
                            }
                        }
                    }
                }
                return _childs;
            }
            #endregion
     
    #region CheckAssemblyName(String name)
            /// <summary>
            /// Vérifie que le nom d'assembly ne soit pas un nom d'assembly système
            /// </summary>
            /// <param name="name">Nom d'assembly à vérifier</param>
            /// <returns></returns>
            public static bool CheckAssemblyName(String name)
            {
                return !name.Contains("Microsoft") &&
                        !name.StartsWith("System") &&
                        !name.Contains("mscorlib") &&
                        !name.Contains("vshost32") &&
                        !name.Contains("PresentationCore") &&
                        !name.Contains("PresentationFramework") &&
                        !name.Contains("WindowsBase");
            }
            #endregion
    Pas grand chose à dire...Je recherche, dans les assemblies chargées/chargeable, tous les types qui héritent de ModelBase pour les conserver dans une liste statique (histoire de pas ré-exécuter le code à chaque appel de cette méthode).

    Déclaration de la classe ModelBase :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract class ModelBase : SerializableModel
    Là encore, dans mes tests, j'ai tenté de déplacer les codes de SerializableModel vers ModelBase...Sans succès bien sur :s

    La seule différence entre mes tests d'avant et maintenant, c'est qu'avant, les fichiers source du projet Silverlight était dans un projet Silverlight directement. Maintenant, ces sources sont dans un projet Library .NET 4 et un autre projet Library Silverlight contient des liens vers ces mêmes sources.

  4. #4
    Invité
    Invité(e)
    Par défaut
    J'avoue je ne comprends pourquoi tu veux changer un code alors que tu dis dans ton précédent post que tout marchait avec WPF et Silverlight.

    Pourquoi avoir mis en commentaires les attributs KnownType et passer par une classe ListChilds ?

    La classe ListChilds sert à quoi ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 35
    Par défaut
    A nononon ^^. Je ne change pas de code.

    J'ai toujours utilisé le KnownType en spécifiant cette méthode ListChilds. Les autres KnownType sont là en guise de test, pour voir si ça fonctionnait mieux en utilisant la déclaration explicite de KnownType plus que l'utilisation d'une méthode de listing des types connus. Ce que je ne comprend pas, c'est pourquoi, du jour au lendemain, une technique que j'avais laissée là (donc a priori, était fonctionnelle) ne fonctionne plus quand je fais mes tests.

    Cette méthode ListChilds est un membre statique de la classe SerializableModel. Elle est chargée de lister tous les types qui héritent de ModelBase dans l'ensemble des assemblies personnalisées chargées (dans le cas d'une application WPF) ou chargeables (dans le cas d'une application Silverlight).

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 35
    Par défaut
    Bon, je ne saurais toujours pas pourquoi l'attribut KnownType avait décidé de ne plus fonctionner, mais j'ai quand même trouvé une solution.

    En plus de KnownType, placé sur le modèle de base et pointant vers une méthode listant les types héritant de SerializableModel (J'ai changé ce comportement...Dans le code présenté ici, ce sont les types héritant de ModelBase), j'ai dû ajouter sur mon contrat de service l'attribut ServiceKnownTypeAttribute.

    D'après ce que j'ai compris, il y a plusieurs méthodes pour indiquer au sérialiseur les types connus :
    1)On peut les renseigner directement dans le code C#, si on accès au DataContractResolver...Pas en Silverlight donc.
    2)Dans le fichier de configuration. Je n'ai pas cherché plus loin là dessus car cette technique oblige à lister tous les types connus à la compilation et non pas à l'exécution...Chose que je ne voulais pas faire.
    3)Ajouter des attributs KnownType au dessus des classes servant de contrat de données. Je n'ai pas d'explication précise (j'ai pas trop cherché faut dire) sur le comportement de ce KnownType...Mais il y a des fois où il ne marche plus en Silverlight (c'était mon problème ici)
    4)Ajouter ServiceKnownTypeAttribute au dessus du contrat de service (là où il y a toutes les déclarations de méthode de service) et l'utiliser de la même manière que KnownType pointant vers une méthode. J'ai repris l'exemple du lien donné et ça marche nickel

    @bientôt

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur de conflit de type
    Par Jhulk dans le forum C
    Réponses: 15
    Dernier message: 16/01/2006, 15h47
  2. Erreur de conversion de type Null en String
    Par navis84 dans le forum Bases de données
    Réponses: 3
    Dernier message: 26/07/2005, 15h25
  3. Fonction divisant argument de type inconnu
    Par Nasky dans le forum C
    Réponses: 9
    Dernier message: 29/07/2003, 00h32
  4. Erreur de cmd GRANT/REVOKE inconnue ss MySQL323.
    Par brnvrl dans le forum Installation
    Réponses: 3
    Dernier message: 06/03/2003, 11h47

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