2010-01-12 8 views
10

J'ai deux services WCF .NET 3.5 construits avec VS2008.Comment empêcher la génération de propriétés "Spécifiées" dans les clients WCF?

J'ai deux clients WCF dans Silverlight pour consommer ces services. Les clients sont générés avec le 'Ajouter une référence de service'. J'utilise Silverlight 4.

Un des proxies est généré avec Specified pour chaque propriété. Ceci est une classe 'message-in' pour ma méthode de service:

// properties are generated for each of these fields 
    private long customerProfileIdField;   
    private bool customerProfileIdFieldSpecified;   
    private bool testEnvField;   
    private bool testEnvFieldSpecified; 

Maintenant, mon autre service (toujours avec un client Silverlight) ne génère pas Specified propriétés.

Maintenant je ne me soucie pas de 'principes de bonne SOA'. Je veux juste me débarrasser de ces foutues propriétés parce que dans le contexte de ce que je fais, je les déteste absolument.

Il doit y avoir une différence entre les deux services - mais je ne veux pas les déchirer complètement pour découvrir la différence.

Un similar question avant avait la réponse 'you cant do it' - ce qui n'est certainement pas vrai parce que je l'ai - je ne sais pas ce que j'ai fait différemment. Editer: Je suis maintenant dans une situation où je régénère mon proxy Silverlight 4 à mon service 3.5 WCF (tous sur la même machine localhost) que parfois j'obtiens des propriétés 'Spécifiées' et parfois je ne le fais pas. Je ne pense plus (comme je le soupçonnais à l'origine) que cela est uniquement dû à une configuration de noeud final ou à un niveau de service [attribut]. Il y a certains déclencheurs dans le message lui-même qui provoquent la génération (ou non) de Spécifié. Il peut y avoir de nombreux facteurs en jeu ou cela peut être quelque chose de très simple.

+0

i ont en fait 3 services qui ne sont pas spécifiées créent des propriétés. Seul le quatrième fait! –

+0

Ajoutez '[XMLSerializerFormat]' aux attributs de votre service: Cochez cette case [answer] (http://stackoverflow.com/questions/13396190/wcf-service-method-arguments-bool-specified) –

Répondre

11

essayer dans votre service WCF où la propriété est déclarée

[DataMember(IsRequired=true)] 
public bool testEnvField { get; set; } 

IsRequired=true niera la nécessité de la propriété testEnvFieldSpecified

+0

Pourquoi ne pas le faire globalement? ? maintenant mon service qui créait des propriétés spécifiées a simplement arrêté de les créer par magie. Je viens d'ajouter un second OperationContract avec un message très similaire - donc je suis toujours coincé sachant ce qui déclenche ce comportement global –

+0

La seule raison pour laquelle je pouvais voir pourquoi 2 proxies généreraient avec SpecifiedField et non, est depuis .n3.5 applications client n'ont pas besoin de la propriété "IsRequired", ils supposent qu'il est vrai par défaut, alors que les applications .net2.0 ont besoin de l'attribut, ils lisent le wsdl différemment. Sont les deux applications SL4? – Neil

+0

@neil est la même application unique! Je suis arrivé à un point où, après avoir recompilé mon application 3.5 et régénéré un proxy pour mon client SL4, je serai parfois «spécifié» et parfois ne le sera pas. ça devient vraiment frustrant! quelque chose dans le datamodel provoque ce comportement –

0

OK, je l'ai trouvé une chose jusqu'à présent qui causera Specified propriétés à être généré:

  • La présence d'un XTypedElement dans le message.

Ils sont utilisés par Linq2XSD. Je retournais un élément d'un modèle Linq2XSD.

Cela a déclenché Specified propriétés à générer tout dans toutes mes classes:

public XTypedElement Foo { get; set; } 

Cependant, cela n'a pas:

public XElement Foo { get; set; } 

Toujours curieux de savoir pourquoi il en est, et s'il y a des d'autres choses qui déclenchent cela.

+0

Je suis soudainement obtenir un problème similaire dans un service Web qui fonctionnait comme écrit, bien que je n'utilise pas XTypedElement ou Linq2XSD, et j'utilise .NET 4.0 – speckledcarp

2

Ces propriétés supplémentaires spécifiées sont générées pour les types de valeur spécifiés comme facultatifs dans le contrat ou le balisage d'attribut.Comme les types de valeurs ont une valeur par défaut, les indicateurs supplémentaires Specified sont ajoutés pour ces propriétés, afin de permettre au client (et au serveur) de faire la distinction entre quelque chose explicitement non spécifié ou explicitement spécifié - qui peut être défini sur valeur par défaut. Sans cela, les entiers finiraient toujours par être 0 (et étant sérialisés) même si vous ne les avez pas définis (à cause du mappage vers int) dans votre code client. Donc, lorsque vous le faites, vous devez également vous assurer que vous avez défini l'indicateur Specified sur true, sinon ces propriétés ne seront pas sérialisées. Par conséquent, pour éviter que ces indicateurs soient générés pour les types de valeur, vous devez modifier le contrat pour rendre ces propriétés de type valeur obligatoires, et non facultatives.

Espérons que cela a du sens.

+1

Droite qui fait p sens erroné SAUF Je ne les obtiens pas toujours générés même pour les types de valeur. Actuellement, tous mes booléens et ints (même non-nullable) ne génèrent PAS ces propriétés, mais parfois je change involontairement quelque chose dans le contrat qui les génère (et je ne suis certainement pas en train d'ajouter accidentellement [DataMember (IsRequired = true)) ]). Je voudrais vraiment savoir comment les désactiver de façon permanente afin qu'ils se comportent comme des objets «normaux». –

+0

Les non-nullable devraient être bien, ce sont les types de valeur * optional * seulement, qui auront ceci. –

+0

c'est l'inverse.C'est le non-nullable champs qui ont besoin des propriétés spécifiées, car sinon vous ne savez pas si la valeur par défaut (false ou 0) est ce que l'utilisateur voulait réellement. les optionnels n'existent tout simplement pas, mais le fait qu'ils soient optionnels dit que c'est ok. dans les deux cas, toutes mes propriétés finissent par obtenir des propriétés spécifiées qui, fondamentalement, vissent complètement tout mon code. il doit y avoir un ensemble de règles qui détermine quand elles sont générées et quand elles ne sont pas. ce n'est pas aussi simple que la nullability unfortunatley (ou heureusement selon la façon dont vous le regardez) –

0

NOTE: Je réalise que c'est une vieille question. J'ajoute ceci ici parce que cette question apparaît comme un résultat supérieur sur Google, et c'est l'information utile pour qui vient chercher.

Essayez d'ajouter cette ligne dans votre déclaration de contrat d'exploitation:
[XmlSerializerFormat]

Il devrait ressembler à ceci:

namespace WebServiceContract 
{ 
    [ServiceContract(Namespace = "http://namespace")] 
    [XmlSerializerFormat] //This line here will cause it to serialize the "optional" parameters correctly, and not generate the extra 
    interface InterfaceName 
    { 
     /*...Your web service stuff here...*/ 
    } 
} 
+1

Notez que cela modifie complètement le moteur de sérialisation XML utilisé pour le service Web. (Passage de DataContractSerializer à XmlSerializer). Le moteur différent utilise un ensemble différent d'attributs pour contrôler la sortie du sérialiseur, a différentes limites de compatibilité et différentes caractéristiques de performance. Ce n'est pas un changement mineur. – Hydrargyrum