2010-11-24 4 views
14

J'ai un service WCF qui retourne une classe qui implémente IExtensibleDataObject. Je dois ajouter un nouveau champ à cette classe. J'ai mis à jour l'interface DataContract et apporté la modification à la classe. Maintenant, quand je tente de lancer mon application client je reçois l'erreur suivante:L'ajout de champ au contrat de données WCF casse les clients?

Could not load file or assembly 'xxx.yyyy.zzzz, Version=1.3.9.26111, Culture=neutral, PublicKeyToken=b09e2f3e9b5894f0' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Le AssemblyVersion de la classe WFC a été modifiée - est-ce que le client de rupture?

EDIT:

Il y a des clients dans la production qui utilisent ce service. Je ne veux pas les faire mettre à jour leur référence de service et redéployer leurs clients pour ce simple changement si possible.

Répondre

25

Cela dépend de la façon dont vous avez configuré votre contrat de données.

Dans WCF, en utilisant tous les paramètres par défaut, votre service utilisera DataContractSerializer (DCS) pour sérialiser votre objet en XML. Le DCS sérialisera vos champs dans l'ordre - d'abord les publics, puis les privés. Dans chaque groupe de visibilité, il classera les champs/propriétés par ordre alphabétique par nom.

Ainsi, si vous présenter une nouvelle propriété publique MiddleName et vous aviez déjà FirstName et LastName, vous seriez bien: le vieux XML aurait été

<YourObject> 
    .... 
    <FirstName>.....</FirstName> 
    <LastName>.....</LastName> 
</YourObject> 

et votre nouveau serait tout simplement ajouter un nouveau propriété à la fin:

<YourObject> 
    .... 
    <FirstName>.....</FirstName> 
    <LastName>.....</LastName> 
    <MiddleName>....</MiddleName> 
</YourObject> 

une telle mise à jour « ajouter quelque chose à la fin » devrait fonctionner très bien, le DCS ignorera tout simplement des balises supplémentaires dans le fichier XML.

Cependant: si vous aviez introduit une propriété appelée Gender, qui serait coincé entre<FirstName> et <LastName> et serait ainsi briser l'ordre des données dans votre XML et serait ainsi rompre le contrat de données - aucun client « ancien » sera être en mesure d'appeler votre nouveau service.

Afin de prendre le contrôle de cela, vous pouvez mettre Order= attributs spécifiques sur vos membres de données dans votre contrat de données:

[DataContract] 
public class SomeAddress 
{ 
    [DataMember(Order=0)] 
    public string FirstName; 

    [DataMember(Order=1)] 
    public string LastName; 
} 

Ensuite, vous pouvez facilement ajouter une nouvelle propriété - il suffit de l'ajouter à la fin de la liste!

[DataContract] 
public class SomeAddress 
{ 
    [DataMember(Order=0)] 
    public string FirstName; 

    [DataMember(Order=1)] 
    public string LastName; 

    [DataMember(Order=2)] 
    public string Gender; 
} 

Ainsi, en utilisant l'attribut Order= sur vos contrats de données, vous pouvez prendre le contrôle de votre mise en page XML, et vous pouvez faire de simples extensions de contrats de données existantes de mises à jour non-rupture.

Pour plus d'informations et un savoir-faire approfondi, vous devriez lire Serialization in Windows Communication Foundation sur le site Web de MSDN Magazine - fortement recommandé.

+0

Je vais essayer cela mais est l'erreur prévue la version "Impossible de charger l'assemblage" que je reçois? – HitLikeAHammer

+0

C'est ce qu'il a fait. Je n'ai pas modifié l'ordre des membres existants mais ajouté Order = 2 aux nouveaux membres. La prochaine version aura Order = 3 sur tous les nouveaux membres et ainsi de suite. – HitLikeAHammer

1

de votre référence de service menu contextuel, choisissez ... « Update Service Reference »

+1

Oui, cela fonctionnera mais j'ai d'autres clients en production. Je voudrais éviter que tout le monde doive recompiler et redéployer - surtout s'il n'a pas besoin du nouveau champ. – HitLikeAHammer