wsdl.exe and Nillable Value Types
Messages   Related Types
This message was discovered on microsoft.public.dotnet.framework.webservices.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
Post a new message to this list...

Erik Klein
I am attempting to use wsdl.exe to generate a Web Service Client in C#
from a valid WSDL file generated by Apache Axis.

My application requires the ability to distinguish between an
unspecified value and a specified value. For that reason, the WSDL
that is generated by Apache Axis utilizes 'nillable="true"' to permit
Web Services Clients to indicate a value or specify 'nil'.

The problem I am having with .NET and wsdl.exe (that I did not have
with Apache Axis and Java Web Services Developer Pack) is with Value
Types.

Here is a portion of the WSDL presenting a problem:
<complexType abstract="true" name="Type">
<sequence>
<element name="localId" nillable="true" type="xsd:string"/>
<element name="id" minOccurs="0" maxOccurs="1" nillable="true"
type="xsd:int"/>
</sequence>
</complexType>

When wsdl.exe generates its class from this, it creates the following:
public abstract class Type {
public string localId;
public int id;
}

The problem is that the "int" is a Value Type that is incapable of
storing null. I have tried the following all to no avail:
1. Replacing 'type="xsd:int"' with 'type="soapenc:int' (which made
Java WSDP work)
2. Including/Removing 'minOccurs' and/or 'maxOccurs'
3. Manually replacing 'public int id' with 'public SqlInt id' (SqlInt
is not the correct name, but its the one from the SQL namespace that
is used to support nulls for ints in the DB ... .NET barked at me when
I attempted to use this telling me it can't be used for XML
serialization or some such thing).

I am out of ideas and wondering if you can guide me to a way to AVOID
having .NET pass a zero(0) when this attribute is not specified (which
is what it currently does for Value Types). I was hoping to find the
equivalent of java.lang.Integer (which can be null) in C# but have had
no success.

One last note: This WSDL will be consumed by clients who purchase the
software I am developing. They will be responsible for generating
their own Web Service Clients using the toolkit of their choice, so I
am trying to make it as standardized as possible while requiring
minimum client intervention/recoding when they generate the Web
Service client.

Thanks in advance for any suggestions.

Erik
Reply to this message...
 
    
Dino Chiesa [Microsoft] (VIP)
Erik, I just tried this using the attached WSDL file and did not see this
behavior.

wsdl.exe generated this for me:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="mynamespacehere")]
public abstract class IdType {
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string localId;
public int Id;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool IdSpecified;
}

The IdSpecified field is set to true or false depending on whether the Id is
nil.
I tried this on input and output messages - same result. It seems to
generate the correct thing.

Can we see the full wsdl you are using?

-Dino

--
Dino Chiesa
Microsoft Developer Division
d i n o c h @ OmitThis . m i c r o s o f t . c o m

"Erik Klein" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Corey Gerritsen
I am having the same problem that Erik is.

I made a simple wsdl from Erik's example and wsdl.exe did not treat either element the way you claimed it did for you.

What version of the Framework are you using, Dino? I am using 1.0.3705 updated to 1.1.

Here is the wsdl I used:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="test" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"; xmlns:tns1="http://test.company.com"; xmlns:impl="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"; xmlns="http://schemas.xmlsoap.org/wsdl/";>
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"; targetNamespace="http://test.company.com";>
<complexType abstract="true" name="Type">
<sequence>
<element name="localId" nillable="true" type="xsd:string"/>
<element name="id" minOccurs="0" maxOccurs="1" nillable="true" type="xsd:int"/>
</sequence>
</complexType>
</schema>
</types>
<wsdl:message name="getTestRequest">
<wsdl:part name="type" type="tns1:Type"/>
</wsdl:message>
<wsdl:message name="getTestResponse">
</wsdl:message>
<wsdl:portType name="TestService">
<wsdl:operation name="getTest" parameterOrder="type">
<wsdl:input name="getTestRequest" message="impl:getTestRequest"/>
<wsdl:output name="getTestResponse" message="impl:getTestResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestServiceSoapBinding" type="impl:TestService">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http";/>
<wsdl:operation name="getTest">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getTestRequest">
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; namespace="referral"/>
</wsdl:input>
<wsdl:output name="getTestResponse">
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; namespace="referral"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestServiceCreator">
<wsdl:port name="TestService" binding="impl:TestServiceSoapBinding">
<wsdlsoap:address location="http://localhost/services/TestService";/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

and here is what was generated:

//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.0.3705.288
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

//
// This source code was auto-generated by wsdl, Version=1.0.3705.288.
//
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;

/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="TestServiceSoapBinding", Namespace="test")]
public class TestServiceCreator : System.Web.Services.Protocols.SoapHttpClientProtocol {

/// <remarks/>
public TestServiceCreator() {
this.Url = "http://localhost/services/TestService";;
}

/// <remarks/>
[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="referral", ResponseNamespace="referral")]
public void getTest(Type type) {
this.Invoke("getTest", new object[] {
type});
}

/// <remarks/>
public System.IAsyncResult BegingetTest(Type type, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("getTest", new object[] {
type}, callback, asyncState);
}

/// <remarks/>
public void EndgetTest(System.IAsyncResult asyncResult) {
this.EndInvoke(asyncResult);
}
}

/// <remarks/>
[System.Xml.Serialization.SoapTypeAttribute("Type", "http://test.company.com";)]
public abstract class Type {

/// <remarks/>
public string localId;

/// <remarks/>
public int id;
}

--------------------------------
From: Corey Gerritsen
Reply to this message...
 
    
Nathan Warren
Erik-

I'm having the same problem you are with a web service of my own. Unfortuneately, Microsoft did not make an easy way to fix this problem, but I would love to see a workaround. I don't have an answer for your problem, but I will shed some light on the responses so far.

Dino-You used the wsdl tool correctly (with the /server tag), but the [System.Xml.Serialization.XmlIgnoreAttribute()] public bool IdSpecified; lines of your generated code are for a different purpose than "nil". When the IdSpecified value is null, this means that the client did not pass the Id value in the soap request. The wsdl attribute that causes this is minOccurs="0". If you were to run your service in IE with the ?WSDL directive, your wsdl would not have nillable="true" attribute in the Id element.

Corey- What you've done is created a client script to consume the web service. You want to use "wsdl /server mywsdl.wsdl" at the command line.

I hope this thread leads to a solution!

--------------------------------
From: Nathan Warren
Reply to this message...
 
    
Nathan Warren
Check this out:

http://www.winisp.net/cheeso/srcview.aspx?dir=xml-serialization&file=XsiNilDate.cs

--------------------------------
From: Nathan Warren
Reply to this message...
 
 
System.AsyncCallback
System.ComponentModel.DesignerCategoryAttribute
System.Diagnostics.DebuggerStepThroughAttribute
System.IAsyncResult
System.Web.Services.Protocols.SoapHttpClientProtocol
System.Web.Services.Protocols.SoapRpcMethodAttribute
System.Web.Services.WebServiceBindingAttribute
System.Xml.Serialization.SoapTypeAttribute
System.Xml.Serialization.XmlElementAttribute
System.Xml.Serialization.XmlIgnoreAttribute
System.Xml.Serialization.XmlTypeAttribute




Ad
MBR BootFX
Best-of-breed application framework for .NET projects, developed by Matthew Baxter-Reynolds and MBR IT
 
 Copyright © Matthew Baxter-Reynolds 2001-2008. '.NET 247 Software Development Services' is a trading style of MBR IT Solutions Ltd.
Contact Us - Terms of Use - Privacy Policy - www.dotnet247.com