2009-11-17 4 views
6

Quelle est la meilleure façon de gérer l'ajout d'un nouveau paramètre (facultatif) à une opération existante sans que le client doive mettre à jour son WSDL? Je ne veux pas mettre à jour l'espace de noms pour décrire une nouvelle version des contrats de service, car cela devrait être rétrocompatible avec les anciens clients.Ajout d'un nouveau paramètre à une opération WCF: choix?

Dois-je ajouter une nouvelle opération avec un nouveau paramètre, en tant que surcharge? Ou devrais-je simplement ajouter le paramètre à l'opération existante?

Voici mon opération:

[OperationContract] 
MyResponse GetData(); 

Faut-il:

[OperationContract] 
MyResponse GetData(); 

[OperationContract] 
MyResponse GetData(string filter); 

Ou plus simplement, il suffit de changer à ceci:

[OperationContract] 
MyResponse GetData(string filter); 

Cette dernière option semble mieux, et selon mon livre de référence, "L'impact sur le client est aucun. Nouveaux paramètres sont initialisés aux valeurs par défaut au service. "WCF l'initialise à la valeur par défaut? Si oui, quelle est la valeur par défaut?

Répondre

13

One La chose à prendre en considération est que vous ne pouvez pas avoir deux OperationContracts avec le même nom.La façon dont il est sérialisé va générer une erreur. La meilleure approche est d'aller avec l'option 3 (en ajoutant simplement le nouveau paramètre) et dans le compte logique de la méthode, car elle est une valeur nulle pour les clients qui n'ont pas encore mis à jour. Si c'est une modification importante que les clients devront mettre à jour, assurez-vous de ne pas faire mourir toute l'application à cause de l'exception.

+2

C'est un changement sans rupture. Je vais gérer si le filtre est nul ou vide gracieusement. –

+0

@Mike: Je ne pense pas que ce soit inégal - soudainement, votre méthode "GetData" attend maintenant un paramètre qui n'est pas fourni par les appelants d'origine .... –

+2

@marc_s: en raison de la flexibilité de WCF aussi longtemps à la valeur peut être nulle, un client qui ne lui passe pas quelque chose fonctionnera toujours. C'est l'avantage d'autoriser la non-concordance de version dans WCF. –

2

Eh bien, changer un contrat existant après qu'il soit utilisé est vraiment contraire à toutes les règles d'orientation de service, vous ne devriez jamais jamais rompre un contrat existant.

En réalité, cela arrive assez souvent, et WCF est assez bien dans la manipulation que pour vous. tant que vous ne créer des changements insécables, les clients existants continueront à travailler.

Cela peut être:

  • un nouveau contrat d'exploitation sur un contrat de service existant
  • un nouveau champ non nécessaire sur un DataContract

Qu'est-ce que vous essayez de faire est de ne pas aller travailler, mais

  1. vous ne pouvez pas avoir deux méthodes avec le même nom dans WCF - WCF est pas .NET et vous ne pouvez pas avoir deux méthodes par le même nom étant différent seulement par leur signature. Ne fonctionne pas Vous devrez utiliser deux noms distincts et distincts. Rappelez-vous: vos appels de méthode WCF seront traduits dans un document WSDL (langage de description de service web) pour décrire le service - et WSDL ne supporte pas simplement deux opérations avec le même nom - juste une différence de signature n'est pas supportée et ne fonctionnera pas .

  2. Vous ne pouvez pas modifier le contrat existant, par ex. vous ne pouvez pas introduire un nouveau paramètre dans un appel de méthode après le fait, sans rompre le contrat.

Donc ce que vous avez vraiment besoin de faire est la suivante:

[OperationContract] 
MyResponse GetData(); 

[OperationContract] 
MyResponse GetFilteredData(string filter); 

Tout autre changement que vous suggérez sera a) rompre le contrat, ou b) tout simplement pas dans WCF:

+0

En fait, je suis allé avec votre suggestion, mais la réponse de Agent_9191 était plus juste au sujet de ma question initiale, donc j'ai accepté sa réponse et + 1'ed vôtre. –

3

vous pouvez essayer ceci:

[OperationContract] 
MyResponse GetData(); 

[OperationContract(Name = "GetDataByFilter")] 
MyResponse GetData(string filter); 
Questions connexes