views:

432

answers:

3

I am developing a WCF service using VSTS 2008 + .Net 3.5 + C# and it works fine when I also use VSTS 2008 to develop client (using Add Service Reference function to automatically generated client web services proxy code). The WCF I developed is using basicHttpBinding.

The issue I met with is, when I use Visual Studio.Net (Visual Studio 2003) to generate client web services proxy code, there is an additional input parameter for a OperationContract method called IdSpecified (bool type). I have tested that when specify IdSpecified to true, the value of Id parameter will be passed to WCF server side correctly, but when I specify IdSpecified to false, no matter what values I specify to Id parameter, at WCF server side, Id will be always 0. I also tried for input parameter type like string, there is no such additional input parameter at client side.

My question is why there is an additional parameter? What is its meaning and is it possible to avoid generate such additional parameter?

Here is Visual Studio.Net automatically generated client side web services proxy code,

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

Here is my VSTS 2008 WCF server side code,

[OperationContract]
StudentInfo Poll(int Id);

EDIT 1: here is part of the automatically generated code at client side about Poll method.

[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]));
}
+1  A: 

You could try using a DataContract rather than a simple integer parameter. The data contract allows you to specify if a member is required or not, which, if the member is required, might remove that weird extra bool.

blowdart
Thanks blowdart, why Visual Studio .Net and VSTS 2008 generates different client proxy code?
George2
BTW: 1. how to specify a parameter is required using DataContract? I searched MSDN but find no answer. 2. Required means client must provide a value?
George2
+1  A: 

here is blog about it

ArsenMkrt
Hi ArsenMkrt, the blog looks very great, but not the same issue as I mentioned here. In the blog, seems the automatically generated client side proxy code contains a property called IdSpecified, but in my scenario, there is no such property, just an additional parameter for the Poll method. You can see my updated code in EDIT 1 section of my original post. Any solutions to my issue?
George2
George, it's the same thing. An extra parameter was added since the int was a parameter, not a property. If you passed a class with a single int property, you'd see a separate IdSpecified property.
John Saunders
It is so great comment, John!
George2
+4  A: 

George,

This behavior is by design, and has been there since .NET 1.0. In fact, if you were to create an ASMX web service with VS2003, with the same method signature, you would find the same result.

The issue is with value types that are marked in the WSDL as not being required. Since they are value types, they can't return null (and VS2003 did not have nullable types). The solution that Microsoft implemented was to add a separate boolean field or property you can set to say whether or not you are supplying the value.

This means that when your .NET 1.1 application wants to call the service, it needs to set the IdSpecified parameter:

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


I haven't tried this, but why don't you:

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

[OperationContract]
public StudentInfo Poll(PollParameters parameters);

Try that and see what the proxy looks like in VS2003.

John Saunders
Thanks John, you are definitely correct -- I am using .Net 1.0 at VS2003. I am interested in the solution you mentioned -- "The solution was to add a separate boolean field you can set to say whether or not you are supplying the value.", could you show me some reference code? Do we solve it at client side or server side?
George2
Sorry I wasn't clear. "The solution" is the one that Microsoft implemented. You're seeing the solution. Note that you have an extra parameter named "IdSpecified". Also, VS2003 is .NET 1.1.
John Saunders
Thanks John, 1. I have read your great code sample and I should wrap every value type into a DataContract and using required attribute? 2. I am curious that VS2003 and VSTS 2008 generates different client side code, either of them are not conforming to Web Services (WSDL) standard?
George2
You _could_ do the wrap. You don't have to. Also the WSDL standard says nothing about client side code.
John Saunders
Hi John, the isrequired attribute is new to me. I read MSDN related document, and want to confirm with you that the meaning of the property means we must explicitly assign value to this property (default value does not mean the value is supplied)? 2. And we can use this property to both input parameter DataMember or return value DataMember to specify mandatority character?
George2
"they can't return null (and VS2003 did not have nullable types)." -- I am confused, I think this rule does not apply to my scenario? The int Id variable is input parameter and not return value, any comments?
George2
Yes, Required means must always be present. In XML Schema that is minOccurs="1". Sorry for my use of the word "return". I mean that an int can never be null. Now in .NET 3.5 in C# 2.0 we can say "int? id", which can be an integer or can be null. We couldn't do that back in .NET 1.0 and 1.1, so Microsoft had to fake it by using the extra "IdSpecified" parameter or property.
John Saunders
Thanks John, I am so impressed by your knowledge. :-)
George2
George, I notice on your profile page you have 343 tags. You've been getting into a very broad range of things yourself. It's almost like you're more than one person, and they all pretend to be George2. Keep up the good work. The quality of your questions improves all the time.
John Saunders