2009-07-26 5 views
1

Je développe un service WCF en utilisant VSTS 2008 + .Net 3.5 + C# et ça fonctionne très bien quand j'utilise aussi VSTS 2008 pour développer un client (en utilisant la fonction Add Service Reference) au code de proxy des services Web client généré automatiquement). Le WCF que j'ai développé utilise basicHttpBinding. Le problème que j'ai rencontré est, lorsque j'utilise Visual Studio.Net (Visual Studio 2003) pour générer le code de proxy des services Web client, il existe un paramètre d'entrée supplémentaire pour une méthode OperationContract appelée IdSpecified (type booléen). J'ai testé que lorsque Spécifier IdSpecified à true, la valeur du paramètre Id sera correctement transmise au serveur WCF, mais quand je spécifie IdSpecified à false, peu importe les valeurs que je spécifie au paramètre Id, côté serveur WCF, Id sera toujours 0. J'ai également essayé pour le type de paramètre d'entrée comme chaîne, il n'y a pas un tel paramètre d'entrée supplémentaire du côté client.VS2003 Web Reference pour un service WCF a un paramètre supplémentaire "IdSpecified"

Ma question est pourquoi il y a un paramètre supplémentaire? Quelle est sa signification et est-il possible d'éviter de générer un tel paramètre supplémentaire?

est ici de Visual Studio.Net côté client généré automatiquement des services Web code proxy,

public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified) 

Voici mon VSTS 2008 code côté serveur WCF,

[OperationContract] 
StudentInfo Poll(int Id); 

EDIT 1: voici une partie de le code généré automatiquement du côté client à propos de la méthode Poll.

[return: System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] 
public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified) { 
    object[] results = this.Invoke("Poll", new object[] { 
       Id, 
       IdSpecified}); 
    return ((StudentInfo)(results[0])); 
} 
+0

[ici] (http://blogs.microsoft.co.il/blogs/oshvartz/archive/2008/09/06/svcutil-generating-wcf-client-and-the-is-is-field-specified-issue .aspx) est blog à ce sujet –

+0

Salut ArsenMkrt, le blog semble très bien, mais pas le même problème que je l'ai mentionné ici. Dans le blog, il semble que le code proxy côté client généré automatiquement contient une propriété appelée IdSpecified, mais dans mon scénario, il n'y a pas de telle propriété, juste un paramètre supplémentaire pour la méthode Poll. Vous pouvez voir mon code mis à jour dans la section EDIT 1 de mon article original. Des solutions à mon problème? – George2

+0

George, c'est la même chose. Un paramètre supplémentaire a été ajouté car l'int était un paramètre, pas une propriété. Si vous transmettez une classe avec une seule propriété int, vous verrez une propriété IdSpecified distincte. –

Répondre

4

George,

Ce comportement est, et a été là depuis la version 1.0 .NET. En fait, si vous créiez un service Web ASMX avec VS2003, avec la même signature de méthode, vous obtiendriez le même résultat.

Le problème est dû au fait que les types de valeur marqués dans le fichier WSDL ne sont pas requis. Comme ce sont des types de valeurs, ils ne peuvent pas retourner null (et VS2003 n'a pas de types Nullable). La solution implémentée par Microsoft consistait à ajouter un champ ou une propriété booléen distinct que vous pouvez définir pour indiquer si vous fournissez ou non la valeur.

Cela signifie que lorsque votre application .NET 1.1 veut appeler le service, il faut régler le paramètre IdSpecified:

using (WebReference1.PollService svc = new WebReference1.PollService()) { 
    StudentInfo info = svc.Poll(id, true); // True to specify 
} 

Je ne l'ai pas essayé, mais pourquoi ne pas :

[DataContract] 
public class PollParameters { 
    [DataMember(Required = true)] 
    public int Id; 
} 

[OperationContract] 
public StudentInfo Poll(PollParameters parameters); 

Essayez cela et voyez à quoi ressemble le proxy dans VS2003.

+0

Merci John, vous avez certainement raison - j'utilise .Net 1.0 à VS2003. Je suis intéressé par la solution que vous avez mentionnée - "La solution consistait à ajouter un champ booléen séparé que vous pouvez définir pour indiquer si vous fournissez ou non la valeur.", Pourriez-vous me montrer un code de référence? Résoluons-nous du côté client ou côté serveur? – George2

+1

Désolé, je n'étais pas clair. "La solution" est celle que Microsoft a implémentée. Vous voyez la solution. Notez que vous avez un paramètre supplémentaire nommé "IdSpecified". En outre, VS2003 est .NET 1.1. –

+0

Merci John, 1. J'ai lu votre exemple de code génial et je devrais envelopper chaque type de valeur dans un DataContract et en utilisant l'attribut requis? 2. Je suis curieux que VS2003 et VSTS 2008 génèrent du code client différent, l'un ou l'autre n'étant pas conforme à la norme WSDL (Web Services)? – George2

1

Vous pouvez essayer d'utiliser un DataContract plutôt qu'un simple paramètre entier. Le contrat de données vous permet de spécifier si un membre est requis ou non, ce qui, si le membre est requis, pourrait supprimer ce bool.

+1

Merci blowdart, pourquoi Visual Studio .Net et VSTS 2008 génèrent du code proxy client différent? – George2

+0

BTW: 1. comment spécifier un paramètre est nécessaire en utilisant DataContract? J'ai recherché MSDN mais n'ai trouvé aucune réponse. 2. Obligatoire signifie que le client doit fournir une valeur? – George2

Questions connexes