C# – VS 2008 wsdl tool converting xsd:positiveInteger to string

cweb serviceswsdl

I have a web service written in C++ using gSoap. One of the methods of the webservice is

int HS__TBusinessComponentGetContents( xsd__positiveInteger pSession, 
xsd__positiveInteger pComponentType, 
xsd__string pPath, 
xsd__string pFilter, 
xsd__string pChangedAfter, 
xsd__positiveInteger pFlags,
xsd__string &rResult);

Using these typedefs:

typedef double                   xsd__double;
typedef wchar_t                 *xsd__string;
typedef bool                     xsd__boolean;
typedef int                      xsd__int;
typedef unsigned long long       xsd__positiveInteger;
typedef wchar_t                 *xsd__datetime;

I generate a wsdl file using this definition which has this (correct) part:

However, when I generate a Proxy class using the Visual Studio 2008 wsdl.exe tool to create a class which I can use from C#, the definition of the above methods is as follows:

[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:tango04-hydra-server", ResponseNamespace="urn:tango04-hydra-server")]
    [return: System.Xml.Serialization.SoapElementAttribute("rResult")]
    public string TBusinessComponentGetContents([System.Xml.Serialization.SoapElementAttribute(DataType="positiveInteger")] string pSession, [System.Xml.Serialization.SoapElementAttribute(DataType="positiveInteger")] string pComponentType, string pPath, string pFilter, string pChangedAfter, [System.Xml.Serialization.SoapElementAttribute(DataType="positiveInteger")] string pFlags) {
        object[] results = this.Invoke("TBusinessComponentGetContents", new object[] {
                    pSession,
                    pComponentType,
                    pPath,
                    pFilter,
                    pChangedAfter,
                    pFlags});
        return ((string)(results[0]));
}

The WSDL is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="Publisher"
 targetNamespace="http://127.0.0.1:18084/Publisher.wsdl"
 xmlns:tns="http://127.0.0.1:18084/Publisher.wsdl"
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:HS="urn:tango04-hydra-server"
 xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
 xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/"
 xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
 xmlns="http://schemas.xmlsoap.org/wsdl/">

<types>

 <schema targetNamespace="urn:tango04-hydra-server"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:HS="urn:tango04-hydra-server"
  xmlns="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">
  <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
 </schema>

</types>

<message name="SessionOpenRequest">
 <part name="vCredentials" type="xsd:string"/>
</message>

<message name="SessionOpenResponse">
 <part name="rResult" type="xsd:positiveInteger"/>
</message>

<message name="SessionCloseRequest">
 <part name="rSession" type="xsd:positiveInteger"/>
</message>

<message name="SessionCloseResponse">
 <part name="rResult" type="xsd:boolean"/>
</message>

<message name="SoapTestRequest">
</message>

<message name="SoapTestResponse">
 <part name="rResult" type="xsd:boolean"/>
</message>

<message name="TBusinessComponentGetContentsRequest">
 <part name="pSession" type="xsd:positiveInteger"/>
 <part name="pComponentType" type="xsd:positiveInteger"/>
 <part name="pPath" type="xsd:string"/>
 <part name="pFilter" type="xsd:string"/>
 <part name="pChangedAfter" type="xsd:string"/>
 <part name="pFlags" type="xsd:positiveInteger"/>
</message>

<message name="TBusinessComponentGetContentsResponse">
 <part name="rResult" type="xsd:string"/>
</message>

<portType name="PublisherPortType">
 <operation name="SessionOpen">
  <documentation>Service definition of function HS__SessionOpen</documentation>
  <input message="tns:SessionOpenRequest"/>
  <output message="tns:SessionOpenResponse"/>
 </operation>
 <operation name="SessionClose">
  <documentation>Service definition of function HS__SessionClose</documentation>
  <input message="tns:SessionCloseRequest"/>
  <output message="tns:SessionCloseResponse"/>
 </operation>
 <operation name="SoapTest">
  <documentation>Service definition of function HS__SoapTest</documentation>
  <input message="tns:SoapTestRequest"/>
  <output message="tns:SoapTestResponse"/>
 </operation>
 <operation name="TBusinessComponentGetContents">
  <documentation>Service definition of function HS__TBusinessComponentGetContents</documentation>
  <input message="tns:TBusinessComponentGetContentsRequest"/>
  <output message="tns:TBusinessComponentGetContentsResponse"/>
 </operation>
</portType>

<binding name="Publisher" type="tns:PublisherPortType">
 <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
 <operation name="SessionOpen">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="SessionClose">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="SoapTest">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="TBusinessComponentGetContents">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:tango04-hydra-server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
</binding>

<service name="Publisher">
 <documentation>Tango/04 Computing Group - Publisher </documentation>
 <port name="Publisher" binding="tns:Publisher">
  <SOAP:address location="http://127.0.0.1:18084"/>
 </port>
</service>

</definitions>

My question is: why is this happening? Shouldn't the parameters be integers, or long long values instead of strings for the parameters that in the wsdl are marked as xsd:positiveInteger? What am I doing wrong here?

Thanks!

Best Answer

This may not be what you want to see but this may help: Microsoft

Basically what it gives you are the .Net datatypes that are associated with each xsd datatype. On that page it shows positiveInteger as a string. So, long story short it's doing what it's supposed to do. If you really want a number data type you may want to maybe look into using a Unsigned data type instead of positive integer, if you need it to always be positive. Otherwise just use an appropriate xsd datatype that will work for you. Since it looks like you have control over the web service and wsdl in c++ this should not be too difficult. If this is not something you want to do you will probably need to add logic checks on your c# client to make sure you are sending a number. Since everything technically goes over the wire as an xml string it technically doesn't matter as long as the service can serialize your request properly. Thus having data checks on your consumer object.

On a side note, when I have needed to develop services in the past we have always handcoded the xsd / wsdl contracts instead of letting tools generate them so we always know exactly what we will get. Not sure if that is what you have done but you could do that as well. When we do this we use the wsdl tool to generate the server proxy and the client proxy so you could generate the server side in cpp and the client in cs and then just fill in the guts the way you need it.

Hopefully that helps you out.

Related Topic