2009-08-20 7 views
1

Supposons que j'ai un service WCF et une méthode dans le contratUtilisation du dictionnaire générique sur wcf: que dois-je rechercher?

<ServiceContract()> _ 
Interface IThingService 
'... 
    <OperationContract()> _ 
    Function GetThing(thingId As Guid) As Thing 
End Interface 

où Thing est une classe ordinaire avec des propriétés ordinaires, à l'exception d'un membre:

Public Class Thing 
    ' ... 
    Public Property Photos() As Dictionary(Of String, Photo) 
    ' ... 
End Class 

où la photothérapie est une classe ordinaire avec propriétés ordinaires.

Alors je me suis plongé dans la documentation, comme this MSDN article et this blog post, et maintenant je suis confus si je dois comprendre beaucoup de choses sur le DataContractSerializer et les détails de la façon dont le service sérialise la propriété Photos.

Ai-je besoin d'y aller, ou y a-t-il quelque chose que je peux faire pour permettre à WCF sur le serveur d'interagir automatiquement avec mon client? Il me semble que tous les détails de sérialisation doivent pouvoir être abstraire loin - je veux juste finir, dans la consommation de l'application client, avec:

Dim foo as Thing = ThingServiceClient.GetThing(someGuid) 
Dim myPhotos as Dictionary(Of String, Photo) = foo.Photos 

Que dois-je faire dans ma définition de chose faire ce travail? Quelque chose que je dois faire ailleurs pour que cela fonctionne? Dois-je m'inquiéter du fait que le service reste fidèle à DataContractSerializer et ne recourt pas à XmlSerializer?

+0

Oh, en passant, cette question découle de ce précédent: http://stackoverflow.com/questions/1294269/getting-bad-generated-code-from-update-service-reference –

+0

Bien qu'il n'y ait pas répondre pour cela encore, nous avons abandonné cette approche pour des raisons de conception sans rapport, donc je n'ai plus besoin de la réponse - même si je voudrais savoir ... –

Répondre

0

Vous devez vous assurer de décorer votre «chose» avec l'attribut [DataContract], et tous ses membres que vous souhaitez inclure dans le contrat de données doivent avoir l'attribut [DataMember]. Il en va de même pour votre classe "Photo".

Tant que vous n'avez pas à gérer le polymorphisme (héritage) et/ou les collections personnalisées, cela devrait l'être, vraiment. Le reste devrait être pris en charge par l'exécution WCF pour vous.

Marc

+0

Je n'ai pas l'attribut DataContract sur aucune de mes classes, et dès que je l'ajoute, je reçois une exception comme suit. Une idée de ce que je fais mal? {"Une erreur s'est produite lors de la réception de la réponse HTTP à localhost/MyService/MyService.svc/... Cela peut être dû au fait que la liaison du noeud final de service n'utilise pas le protocole HTTP. serveur (peut-être en raison de l'arrêt du service) Voir les journaux du serveur pour plus de détails. "} –

+0

Quelle liaison utilisez-vous? Et que vous disent les journaux de serveur? –

+0

basicHttpBinding, et il n'y a rien dans les journaux du serveur. –

1

je serais prudent avec vous exposer des objets d'affaires directement dans un contrat de WCF (ou un service Web ASMX, ou tout autre point d'entrée externe dans le système). C'est une interface que vos systèmes externes utilisent, et une telle interface devrait rester constante même si vos objets métier changent en interne. Il peut également y avoir des fonctions sur l'objet métier qui ont du sens sur le serveur, mais pas sur le client.

De même, vous devez soudainement modifier vos objets d'entreprise pour qu'ils correspondent à la technologie de communication de votre choix, par ex. vous devez mettre des attributs sur votre classe affaires, des attributs qui n'ont vraiment rien à voir avec la classe business.

Je créerais un ThingDTO (DTO = objet de transfert de données) qui contient les données à transférer au client et l'initialise avec les données d'une instance Thing. Cela signifie que si vous considérez votre service WCF comme une façade du système, le ThingDTO fait alors partie de votre couche de façade. Et donc les attributs pour contrôler la sérialisation WCF peuvent aller librement ici. Cela dit, ce n'est pas la même chose que cela a du sens dans votre cas. C'est juste mon point de vue général sur le retour des classes d'affaires à partir d'une interface WCF.

+0

Je suis d'accord, mais j'espérais aussi avoir une réponse à ma question. Personne ne sait? –

1

J'ai failli me tuer en essayant de résoudre ce problème. A la fin, je suis toujours en vie et avec un code sympa et petit.Profitez :)

[DataContract, Serializable] 
[KnownType("GetKnownTypes")] 
public class Dto 
{ 
    [DataMember] 
    public Int PropertyA { get; set; } 

    [DataMember] 
    public String PropertyB { get; set; } 

    [DataMember] 
    public Dictionary<string, object> MyDictionary { get; set; } 

    private static Type[] GetKnownTypes() 
    { 
     return _myDictionaryValueTypes ?? new Type[] { Typeof(Dictionary<string, object>) }; 
    } 

    private void MyDictionaryValueTypes() 
    { 
     if (XmlDictionary == null) return; 
     _myDictionaryValueTypes = XmlDictionary.Values.Where(value => value != null).Select(value => value.GetType()).ToArray(); 
    } 
} 

La seule chose que vous devez vous assurer est d'appeler MyDictionaryValueTypes et c'est tout.

Questions connexes