Search code examples
c#web-serviceswsdl

What's the problem with this web service method?


Update: Problem solved.


I have to call a web service method (dduLogin), which returns 3 parameters. I generated the code by "adding a web reference" through visual studio. This is the relevant part of the wsdl:

<message name="dduLoginRequest">
    <part name="Ticket" type="xsd:string"/>
    <part name="ServiceId" type="xsd:string"/>
    <part name="Market" type="xsd:string"/>
    <part name="Application" type="xsd:string"/>
    <part name="Brand" type="xsd:string"/>
    <part name="Sincom" type="xsd:string"/>
    <part name="CertificationSystem" type="xsd:string"/>
</message>  


<message name="dduLoginResponse">
    <part name="Ticket" type="xsd:string"/>
    <part name="LoginId" type="xsd:string"/>
    <part name="Return" type="xsd:string"/>
</message>
<portType name="dduPortType">
    <operation name="dduLogin">
        <input message="tns:dduLoginRequest"/>
        <output message="tns:dduLoginResponse"/>
    </operation>


</portType>
<binding name="dduBinding" type="tns:dduPortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="dduLogin">
        <soap:operation soapAction="urn:ddu#dduLogin" style="rpc"/>
        <input>
            <soap:body use="encoded" namespace="urn:ddu" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
        </input>
        <output>
            <soap:body use="encoded" namespace="urn:ddu" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
        </output>
    </operation>


</binding>

It's possible to call this method, and this is the xml that is returned:

<SOAP-ENV:Body><ns1:dduLoginResponse xmlns:ns1="urn:ddu">
    <Ticket xsi:type="xsd:string">M-S%40%2AT6%2F%26179G%23%24%25%25%2A%40%40LDNT%27BP%3F9C%2CRY9-Z8C0C%3D0JXD%24_%2A%5EFKF%26DV%3BIP_8%3DM.E3VBDU7%3CAB%5C9_%22%3A%29E9%2CYO6%5C8I%5D6J%5EZ%60%2C8%3A%26%60%25U%3B.6A4G%2BO%5EQA%5DINI4X2%247%29M%2C%3B%3DZ%5CQ%3C%3A%27%3AB%5CSUB%3F9GAPC%3DRV%3CA%5E%2CE7%40L3%3F%3FY%215T%27%40B%3FKUJIH%3D%2B150Q%3CD%3A%3B%21D%22%3B%3ED%60%60%0A</Ticket>
    <LoginId xsi:type="xsd:string">22459</LoginId>
    <Return xsi:type="xsd:string">0</Return></ns1:dduLoginResponse>
</SOAP-ENV:Body>

But after the call, not all the return values are filled as they should be. This is the by Visual Studio generated code for that method:

[System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:ddu#dduLogin", RequestNamespace="urn:ddu", ResponseNamespace="urn:ddu")]
[return: System.Xml.Serialization.SoapElementAttribute("LoginId")]
public string dduLogin(ref string Ticket, string ServiceId, string Market, string Application, string Brand, string Sincom, string CertificationSystem, out string Return) {
    object[] results = this.Invoke("dduLogin", new object[] {
        Ticket,
        ServiceId,
        Market,
        Application,
        Brand,
        Sincom,
        CertificationSystem});
    Ticket = ((string)(results[1]));
    Return = ((string)(results[2]));
    return ((string)(results[0]));
}

It's like the results are in the wrong order (ticket should be results[0]), and LoginId should be results[1] and results[1] is also empty (null).

What's the problem here? Am I missing something? Is it a bad wsdl? Is it the Visual Studio Web Service Proxy generator? Someone had this before? Any suggestions on how to solve this?

Btw, a co-worker is able to call this web service successfully using another web service toolset (totally not .NET related).

Edit: here is the output from wsdl.exe for the wsdl in question:

C:\temp>wsdl https://eu.link.fiatauto.com/tsi/DDUWsAut.php?wsdl
Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 2.0.50727.3038]
Copyright (C) Microsoft Corporation. All rights reserved.
Warning: This web reference does not conform to WS-I Basic Profile v1.1.
R2706: A wsdl:binding in a DESCRIPTION MUST use the value of "literal" for the u
se attribute in all soapbind:body, soapbind:fault, soapbind:header and soapbind:
headerfault elements.
  -  Input element soapbind:body of operation 'dduLogin' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduLogin' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduLogout' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduLogout' on portType 'dduBindi
ng' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduDir' on portType 'dduBinding'
from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduDir' on portType 'dduBinding'
 from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduGetGroupList' on portType 'ddu
Binding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduGetGroupList' on portType 'dd
uBinding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduGetGroupFileList' on portType
'dduBinding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduGetGroupFileList' on portType
 'dduBinding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduCreate' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduCreate' on portType 'dduBindi
ng' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduOpen' on portType 'dduBinding'
 from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduOpen' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduClose' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduClose' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduAbort' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduAbort' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduRead' on portType 'dduBinding'
 from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduRead' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduWrite' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduWrite' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduGet' on portType 'dduBinding'
from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduGet' on portType 'dduBinding'
 from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduPost' on portType 'dduBinding'
 from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduPost' on portType 'dduBinding
' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduGetAtt' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduGetAtt' on portType 'dduBindi
ng' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduPostAtt' on portType 'dduBindi
ng' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduPostAtt' on portType 'dduBind
ing' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduTransaction' on portType 'dduB
inding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduTransaction' on portType 'ddu
Binding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduCommit' on portType 'dduBindin
g' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduCommit' on portType 'dduBindi
ng' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduRollback' on portType 'dduBind
ing' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduRollback' on portType 'dduBin
ding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduLoginDescr' on portType 'dduBi
nding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduLoginDescr' on portType 'dduB
inding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduIsRemoteDebug' on portType 'dd
uBinding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduIsRemoteDebug' on portType 'd
duBinding' from namespace 'urn:ddu'.
  -  Input element soapbind:body of operation 'dduLogClient' on portType 'dduBin
ding' from namespace 'urn:ddu'.
  -  Output element soapbind:body of operation 'dduLogClient' on portType 'dduBi
nding' from namespace 'urn:ddu'.

For more details on the WS-I Basic Profile v1.1, see the specification
at http://www.ws-i.org/Profiles/BasicProfile-1.1.html.

Writing file 'C:\temp\ddu.cs'.

Update

I've followed @Benjamin's advice, and used WCF to create a client. I did have some problems though: the wsdl contained some spaces where there shouldn't be spaces, and the encoding of the service apparently was ISO-8859-1, so I ended up creating my own CustomTextMessageEncoder.

As I am anticipating more problems down the road with this service, I'm still very interested in getting this to work with the old style web service references, so if anybody has another clue why the returned xml isn't parsed right, here is the url to the wsdl:

https://eu.link.fiatauto.com/tsi/DDUWsAut.php?wsdl

Note that removing the spaces (which was the problem I encountered while trying the service reference way) did not solve this issue (the output from wsdl.exe is still the same without the spaces).


Solution

  • I raised the issue with the provider of the service, and after quite some troubleshooting (they weren't able to reproduce it first), it became clear that there are apparently 2 different endpoints for the same service:

    The default one which I was using:

    https://eu.link.fiatauto.com/tsi/DDUWsAut.php

    and another one they were using (apparently specifically for dotnet clients):

    https://eu.link.fiatauto.com/tsi/DDUWsAutDotNet.php

    Why that would be needed is still not clear to me, but using the dotnet specific endpoint in stead of the other one solved my problem, so I asked no further questions.