interoperability between GSOAP and .NET
The key point is about namespace.
1. How to use gsoap DOM parser to generate xsd:anyType node
extern "C" ACE_Svc_Export soap_dom_element factory()
{
xsd__int ret = main_entry();
struct soap soap;
soap_init(&soap);
soap_set_imode(&soap, SOAP_DOM_NODE);
xsd__int domval=ret ; //we have to use this type
soap_dom_element retDomVal(&soap, "mcws", NULL, &domval, SOAP_TYPE_xsd__int);
//”mcws” ----- must use the namespace which is the same defined in WSDL
// NULL ------ must be NULL else this name will be used as TAG name in the soap message
return retDomVal;
}
2. the result soap message generated by GSOAP, which is exactly specified in WSDL. Such that .NET client can parse it out correctly.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope 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:mcws="http://www.binghamton.edu/mcwsDocu">
<SOAP-ENV:Body>
<mcws:invokeCodeResponse>
<mcws:value xsi:type="xsd:int">49</mcws:value>
<mcws:ret>0</mcws:ret>
</mcws:invokeCodeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
3. GSOAP wsdl
<message name="installCodeResponse">
<part name="parameters" element="mcws:installCodeResponse"/>
</message>
<element name="invokeCodeResponse">
<complexType>
<sequence>
<element name="value" type="xsd:anyType" minOccurs="1" maxOccurs="1"/>
<element name="ret" type="xsd:int" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
4. Debugging && trouble shooting
4.1 on GSOAP side, define DEBUG in the compiler for example –DDEBUG
Then we will get SEND.log and RECV.log in the current working directory
4.2 on DOTNET side, we can add code into client stub (generated by wsdl.exe or “update web reference”
Override public partial class McwsDocu : System.Web.Services.Protocols.SoapHttpClientProtocol
….
protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize)
Add references
using System.Net;
using System.IO;
using System.Xml;
using System.Text;
Implementation
/* copy stream to another stream*/
private void Copy(Stream streamFrom, Stream streamTo)
{
TextReader reader = new StreamReader(streamFrom);
TextWriter writer = new StreamWriter(streamTo);
String line;
line = reader.ReadLine();
while (line != null)
{
writer.WriteLine(line);
line = reader.ReadLine();
}
writer.Flush();
}
/* will generate log file for incoming soap message to c:\\log.txt */
protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize)
{
MemoryStream m = new MemoryStream();
Copy(message.Stream, m);
m.Seek(0, SeekOrigin.Begin);
Double now = System.DateTime.Now.ToOADate();
FileStream fs = new FileStream("c:\\log.txt", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter w = new StreamWriter(fs); // create a Char writer
w.BaseStream.Seek(0, SeekOrigin.End); // set the file pointer to the end
TextReader reader = new StreamReader(m);
String line;
while ((line = reader.ReadLine()) != null)
{
w.WriteLine(line);
}
w.Flush();
w.Close();
m.Seek(0, SeekOrigin.Begin);
XmlTextReader xmlreader;
xmlreader = new XmlTextReader(m);
xmlreader.ProhibitDtd = true;
xmlreader.Normalization = true;
xmlreader.XmlResolver = null;
return xmlreader;
}