How does the MSFT Web Service Proxy Generator figure out .NET object types?

P

psparago

Hi,

I'm probably missing something obvious, but I'd like to know how the
Web Service Proxy Generator in .NET 2003 figures out from a WSDL the
correct type of a .NET object method parameter or result when there is
no information about the type in the WSDL? Does it call each method and
interrogate the response XML?

I can understand that an xsd:any reference tells the WSDL consumer that
a particular particle is expected to be determined at run time and an
<element type='xsd:schema'> says an XML Schema will be returned in the
response message to describe the object, but the schema itself is not
referenced in the WSDL. Yet, the proxy knows the correct type! I hate
MSFT magic!

Does anyone know? Am I just being dense?

thanks
peter
 
D

Dan Rogers

Hi,

The WSDL is all that the proxy generator (actually XSD.exe) uses. I'd need
more specifics on your exact situation to help you. An xsd:any does not
imply anything, btw, and there is no inspection of the methods by the proxy
generator at run time.

I hope this helps

Dan Rogers
Microsoft Corporation
--------------------
 
P

psparago

Hi Dan,

Thank you for the speedy response.

Say for example, I have the following Web Method:

[WebMethod]
public void datasetTest(out System.Data.DataSet dataset) {
try {
dataset = new System.Data.DataSet();
} catch(Exception e) {
throw e;
}
}

The relevant portion of the WSDL looks like this:

<s:element name="datasetTest">
<s:complexType />
</s:element>
<s:element name="datasetTestResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="dataset">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>

However, when I generate a Web Reference for the Web Method above, I
get the following proxy implementation:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute
("http://tempuri.org/datasetTest",
RequestNamespace="http://tempuri.org/",
ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return:
System.Xml.Serialization.XmlElementAttribute("dataset")]
public System.Data.DataSet datasetTest() {
object[] results = this.Invoke("datasetTest", new
object[0]);
return ((System.Data.DataSet)(results[0]));
}

As you can see, a proxy method gets generated that returns a
System.Data.DataSet .NET object.

My question is, How did Visual Studio's proxy generator know that the
'out' argument (which somehow became the result, but that's another
story) was actually a System.Data.DataSet object?

Thanks for the help,

peter
 
D

Dan Rogers

Hi Peter,

I think it's safe to assume that when it sees this...


<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="dataset">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>

... that an assumption is made that the programmer exposed a dataset. If
you look at this, a schema followed by an any is a pretty wierd structure -
but it will suffice for the java implementaitons out there that will have
to just treat this as a schema followed by an XML blob.

The alternative would be to make the proxy that is generated not assume
anything and expose a return type of XmlNode - which would not be very
useful in a Microsoft on both sides of the wire case. So you are right,
the assumption is a bit of magic, but a pretty safe and simple one. In
the end, if the implementation does NOT return a dataset, the load will
fail at runtime.

As for why this is a return type versus an out variable, it's all the same
on the wire since you can only return a single type from a web service
(this is because SOAP requires that there be only one element child under
body). Making it a return type simplifies the programming model.

Hope this clarifies

Regards

Dan
 
P

psparago

Hi Dan,

Well, you verified what I already knew: I am an idiot and a dense one
at that!

I totally missed the name= attribute. I spent hours trying to figure
this out. Doesn't say much for me, does it? :)

Anyway, thank you very, very much for your quick and clear answer. I
really appreciate it.

peter
 
P

psparago

Hi again Dan,


I think I declared victory too soon. After looking back at the example,
I realized that I had named the 'out' parameter 'dataset'. I changed
the Web Service so that the 'out' parameter was now named 'foo'

[WebMethod]
public void datasetTest(out System.Data.DataSet foo) {
try {
foo = new System.Data.DataSet();
} catch(Exception e) {
throw e;
}
}

And this is now the relevant part of the WSDL:

<s:element name="datasetTest">
<s:complexType />
</s:element>
<s:element name="datasetTestResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="foo">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>

Yet, when I update the Web Reference, the proxy looks like:


[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/datasetTest",
RequestNamespace="http://tempuri.org/",
ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("foo")]
public System.Data.DataSet datasetTest() {
object[] results = this.Invoke("datasetTest", new
object[0]);
return ((System.Data.DataSet)(results[0]));
}

It STILL figured it out!!!! How??

thanks again,

peter
 
P

psparago

Hi Dan,

A colleague of mine just pointed out that you weren't referring to the
name='dataset' attribute but the fact that there was a schema followed
by an any. Thus, I can assume that this is a 'special' construct that
Microsoft interprets as a DataSet reference. Is that right?
Thanks again,
peter
 
D

Dan Rogers

Hi Peter,

Yes, the construct of returning a schema followed by an object is a pretty
wierd one that I would expect to see very few schema authors choose to use
since it provides no real data about the service types. In this case, I
think the PM's assumed it was a safe bet that no-one would do this, and if
they did and we couldn't load it into a dataset, then one gets what you get
for defining such an odd interface.

Hope this helps

Dan
--------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top