Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

WCF : KnownType - Comment retourner des types enfants du type définit dans le ServiceContract

Lorsque vous créez un service WCF, vous allez créer un contrat. Dans la plupart des cas, ce contrat est une interface décorée de l'attribut ServiceContract contenant des méthodes décorées de l'attribut OperationContract.

Si vous voulez retourner un objet d'un type enfant du type déclaré vous obtiendrez une exception de type : "CommunicationException".

Prenons cet exemple :

[ServiceContract] public interface IMyService { [OperationContract] Animal GetAnimal(String name); } [DataContract] public abstract class Animal { } [DataContract] public class Dog : Animal { } [DataContract] public class Cat : Animal { }

L'implémentation de ce contrat retournera soit un objet de type Dog ou un objet de type Cat suivant la valeur du paramètre name.

Lors de l'utilisation de ce service vous obtiendrez une CommunicationException :

There was an error while trying to serialize parameter http://tempuri.org/:query. The InnerException message was 'Type 'Test.Dog' with data contract name 'Dog:http://schemas.datacontract.org/2004/07/Test.Doc' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

La raison est que vous retournez un objet qui n'est pas connu du service, il ne sait alors pas comment le sérialiser. Pour palier à ce problème, il faut faire connaitre ces types à notre service. Il existe plusieurs solutions :

  • Utilisation de l'attribut ServiceKnownType : Cet attribut s'utilise au niveau du contrat soit sur la définition de l'interface, soit sur les différentes méthodes de l'interface :

[ServiceContract] public interface IMyService { [OperationContract] [ServiceKnownType(typeof(Dog))] [ServiceKnownType(typeof(Cat))] Animal GetAnimal(String name); }

  • Utilisation de l'attribut KnownType : Cet attribut s'utilise au niveau de la classe mère :

[DataContract] [KnownType(typeof(Dog))] [KnownType(typeof(Cat))] public abstract class Animal { }

<configuration> <system.runtime.serialization> <dataContractSerializer> <declaredTypes> <add type="Test.Animal, MyAssembly"> <knownType type="Test.Dog, MyAssembly"/> </add> <add type="Test.Animal, MyAssembly"> <knownType type="Test.Dog, MyAssembly"/> </add> </declaredTypes> </dataContractSerializer> </system.runtime.serialization> </configuration>

Il existe d'autres solutions, mais toutes dérives de ces 3 solutions. J'aime particulièrement la solution qui consiste à appeler une méthode static d'un certain type, cette solution permet d'inclure des KnownType générique ou alors d'inclure tous les enfants d'un type via de la reflection.

Pour en savoir plus sur comment référencer vos types dans le contrat, je vous conseille cet article : All about knownTypes ou cet article MSDN : Data Contract Known Types

Posted: jeudi 12 juin 2008 15:55 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

olrt a dit :

Cette solution de décoration marche effectivement pour permettre de transporter des types dérivés du DataContract de base.

En revanche, elle n'est pas souple car elle crée des dépendances entre la classe de base et les classes dérivées : pour chaque nouvelle classe dérivée , il faudra ajouter un nouvel attribut KnowType. Cela rend difficile la conception de software frameworks, où l'on veut découpler les classes de bases (classes d'architecture) et les classes dérivées (classes implémentées par les développeurs).

Pour éviter de décorer le servicecontract, il existe une solution (plus compliquée), qui consiste à déléguer la (dé)sérialisation des types par le NetDataContractSerializer. En effet, le NetDataContractSerializer (dé)sérialise l'information de type, contrairement au DataContractSerializer.

La solution complète se trouve

<a href="http://www.business-patterns.com/BlogCorner/tabid/56/EntryID/13/Default.aspx">ici</a>

# juin 29, 2008 18:52
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Office 365: Nettoyage des versions de List Item avant migration depuis SharePoint On Premise vers SharePoint Online par Blog Technique de Romelard Fabrice le 08-08-2017, 15:36

- Office 365: Comment supprimer des éléments de liste SharePoint Online via PowerShell par Blog Technique de Romelard Fabrice le 07-26-2017, 17:09

- Nouveau blog http://bugshunter.net par Blog de Jérémy Jeanson le 07-01-2017, 16:56

- Office 365: Script PowerShell pour assigner des droits Full Control à un groupe défini par Blog Technique de Romelard Fabrice le 04-30-2017, 09:22

- SharePoint 20XX: Script PowerShell pour exporter en CSV toutes les listes d’une ferme pour auditer le contenu avant migration par Blog Technique de Romelard Fabrice le 03-28-2017, 17:53

- Les pièges de l’installation de Visual Studio 2017 par Blog de Jérémy Jeanson le 03-24-2017, 13:05

- UWP or not UWP sur Visual Studio 2015 ? par Blog de Jérémy Jeanson le 03-08-2017, 19:12

- Désinstallation de .net Core RC1 Update 1 ou SDK de Core 1 Preview 2 par Blog de Jérémy Jeanson le 03-07-2017, 19:29

- Office 365: Ajouter un utilisateur ou groupe dans la liste des Site collection Administrator d’un site SharePoint Online via PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-24-2017, 18:52

- Office 365: Comment créer une document library qui utilise les ContentTypeHub avec PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-22-2017, 17:06