3

I'm trying to write a C# .NET app that can deserialize a SOAP response from a webservice. The webservice (here called 'Wibble') has no WSDL (Grrrrrrr). I have a copy of a complete sample response which I believe I can use to generate intermediate classes, but despite trying a number of different methods, I can't get a sane object from the response.

The first few lines of the response looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns1:inspectResponse xmlns:ns1="ProjectService" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <inspectReturn href="#id0"/>
        </ns1:inspectResponse>
        <multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="Wibble" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Project">
            <category xsi:type="ns2:Category" xsi:nil="true"/>
            <classId xsi:type="xsd:long">1000000</classId>
            [...]
        </multiRef>
        <multiRef xmlns:ns3="Wibble" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:ProjectData">
            <author xsi:type="ns3:User" xsi:nil="true" />
            <authorUserId xsi:type="xsd:long">5289027</authorUserId>
            <classId xsi:type="xsd:long">0</classId>
            <comments xsi:type="xsd:string">Some comments.</comments>
            [...]        
        </multiRef>
    </soapenv:Body>
</soapenv:Envelope>

etc...

Firstly, if I try to use a SoapFormatter like this:

var formatter = new SoapFormatter();
var blah = formatter.Deserialize(memstream);
return blah.ToString();

I get a SerializationException: Parse Error, no assembly associated with Xml key ns1 inspectResponse

So I guess it's missing a class called inspectResponse that it can map the first element onto. So I crack out xsd.exe and generate some xsds from the XML file. From here, I generate a 52KB C# class that contains a whole bunch of code that (I'm guessing) contains all the classes that the XML file can map to. I include that, and re-run the above code and get exactly the same error.

So then I get the idea that now I have the auto-generated classes, I can just use an XmlSerializer object and try and deserialize that way. I write this:

var ss = new XmlSerializer(typeof(Classes.Envelope));
object blah;
using (var xr = XmlReader.Create(new StringReader(response)))
{
    ss.Deserialize(xr);
    blah = ss.Deserialize(xr);
}
return blah.ToString();

This time I get a new InvalidOperationException: There is an error in XML document (2, 356). ---> System.InvalidOperationException: The specified type was not recognized: name='Project', namespace='Wibble', at <multiRef xmlns=''>.

The auto-generated code doesn't contain a Project class, although it does contain a multiRef class. Presumably it's barfing because no Project class exists. I try creating a placeholder:

[Serializable]
[XmlType(TypeName = "Project", Namespace = "Wibble")]
public class Project
{
}

but that has no effect.

Am I way off the mark here, or am I just missing some small thing? I appreciate it's a fairly complex XML response with multiple multiRef elements all of different types, but I would have expected that the SoapSerializer should have been able to do something with it.

growse
  • 3,554
  • 9
  • 43
  • 66
  • similar question: http://stackoverflow.com/questions/9264048/generate-wsdl-for-existing-soap-service-using-captured-traffic – Giedrius Sep 04 '12 at 11:55
  • Generating a WSDL from some XSDs seemed like a brilliant idea, until it turned out that http://www.theprogrammerfactory.com/ is down. – growse Sep 04 '12 at 12:26
  • there should be alternatives for that, some here, but not sure if all: http://stackoverflow.com/questions/920086/generating-a-wsdl-from-a-xsd-file – Giedrius Sep 04 '12 at 12:39

1 Answers1

1

Okay, why dont you try loading the response into an XMLDomDocument and use XPATH expressions or XSLT to query the nodes that you are interested in. Then a custom mapper class could map the node attributes into your POCO classes.

Just a thought and a bad work around in case you dont find anything else, but I am surprised that a SOAP return message has no WSDL to it. Is this a public service .

Have you also tried appending ?WSDL at the end of the service URL and see what happens.

Vishnoo Rath
  • 550
  • 7
  • 22
  • I think this might have to be my fallback. I've had many back and forths with the service developers about the lack of WSDL. There just isn't one. They're 'thinking' about developing one though. – growse Sep 04 '12 at 14:01