2010-10-27 7 views
1

J'essaie de créer un service WCF, mais j'ai rencontré un problème de blocage. J'ai fait du googling mais je n'ai pas réussi à progresser. J'espère avoir plus de chance ici.Sérialisation du service WCF: Le désérialiseur n'a aucune connaissance d'aucun type qui correspond à ce nom

Disons que j'ai une classe d'emploi défini comme tel:

[DataContract] 
public class Job : IJob 
{ 
    public Job(...) 
    { 
    } 

    [DataMember] 

    public string Example 
    { 
     get { return m_example; } 
     set { m_example = value; } 
    } 
} 

Maintenant, ce que je fais est quelque chose comme ça

public void DoSomething() 
{ 
    ExampleServiceProxy.ExampleClient proxy = new ExampleServiceProxy.ExampleClient(); 
    proxy.DoSomething(job); 
} 

A l'intérieur de mes Reference.cs J'ai ajouté quelques ServiceKnownTypeAttribute comme suit:

... 
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(Job))] 
void DoSomething(object job); 

Mon code de service est le suivant:

[ServiceContract] 
public interface IExample 
{ 
    [OperationContract] 
    void DoSomething(IJob); 
} 

public class Example : IExample 
{ 
    public void DoSomething(IJob job) 
    { 
     ... 
    } 
} 

Ai-je besoin de mettre un peu plus loin ServiceKnownTypeAttributes quelque part? Ai-je besoin de réimplémenter l'objet du côté service?

Répondre

4

Vous devez mettre le ServiceKnownType attribut sur l'interface du contrat de service.

[ServiceContract] 
public interface IExample 
{ 
    [OperationContract] 
    [ServiceKnownType(typeof(Job))] 
    void DoSomething(IJob); 
} 

public class Example : IExample 
{ 
    public void DoSomething(IJob job) 
    { 
     ... 
    } 
} 
+0

J'ai essayé de le faire plus tôt, mais j'ai une erreur qui introduirait une dépendance circulaire. C'est parce que Job.cs est dans une autre assemblée et je devrais l'inclure dans le projet WCF (je pense). – PolandSpring

+2

OK. Vous n'avez pas d'autre choix que de refactoriser vos bibliothèques pour supprimer les dépendances circulaires. Avoir les définitions ServiceContract, IJob et Job dans une seule librairie. Ensuite, avoir l'implémentation du serveur dans un autre exécutable ou une bibliothèque, et le client dans un autre exécutable. Lorsque vous programmez en WCF, vous vous êtes habitué à créer beaucoup de bibliothèques. –

+0

Merci, je l'ai fait et ça a bien fonctionné. – PolandSpring

-1

Y a-t-il une raison pour laquelle vous utilisez l'interface IJob? Je n'ai jamais vu la WCF implémentée de cette façon.

Lorsque j'implémente WCF, j'utilise toujours le DataContract, c'est-à-dire Job. Je fais cela parce que le contrat de données est le contrat entre les deux parties, et n'a aucun comportement. Lorsque le service a un comportement, utiliser une interface est une bonne idée.

Le DataContract doit également être défini du côté Service. Donc, si vous deviez déplacer Job dans la bibliothèque Service, supprimer IJob, supprimer la référence existante dans le client et la régénérer, cela fonctionnera correctement.

Voici le code de service:

[ServiceContract] 
public interface IExample 
{ 
    [OperationContract] 
    void DoSomething(Job); 
} 

[DataContract] 
public class Job 
{ 
    public Job(...) 
    { 
    } 

    [DataMember] 

    public string Example 
    { 
     get { return m_example; } 
     set { m_example = value; } 
    } 
} 

public class Example : IExample 
{ 
    public void DoSomething(Job job) 
    { 
     ... 
    } 
} 
+0

Cela ferait-il vraiment une différence (ne sait pas du tout) puisque Job est une implémentation de l'interface IJob. – PolandSpring

+0

Bon point, "Ne fais pas ça" est une mauvaise forme. – Iain

+0

C'est une mauvaise forme de répondre à une question avec "Ne fais pas ça", sans même essayer de répondre à la question. Si vous voulez vraiment le dire, attendez d'avoir suffisamment de rep pour ajouter un commentaire. –

Questions connexes