vrijdag 4 april 2008

Communicating with a PERL web service

Sometimes you have communicate with a existing web services, and there is just no documentation or WSDL. In my case the web service was written in Perl. You can take these steps to try to generate a decent proxy for the web service.

First sniff the network so you have the exact request and response.

Sample request:

POST /PERL.asmx HTTP/1.1
SOAPAction : PERLWebserviceMethods#SomeMethod
Content-Type : text/xml
Host : localhost:2353
Content-Length : 544
Connection : Keep-Alive

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SomeMethod xmlns="PERLWebserviceMethods">
<ipaddress xsi:type="xsd:string">86.87.60.177</ipaddress>
</SomeMethod>
</soap:Body>
</soap:Envelope>


Sample Response (body):


<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SomeMethodResponse xmlns="PERLWebserviceMethods">
<foo xsi:type="xsd:string">blabla</foo>
<bar xsi:type="xsd:string">1</bar>
</SomeMethodResponse>
</soap:Body>
</soap:Envelope>

Then we craft a web service mimicking the PERL web service.

[WebService(Namespace = "PERLWebserviceMethods")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class PERLWebservice : System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod(ResponseNamespace = "PERLWebserviceMethods",
ResponseElementName = "SomeMethodResponse",
ParameterStyle = SoapParameterStyle.Bare,
Action = "PERLWebserviceMethods#SomeMethod")]
public SomeMethodResponse SomeMethod(SomeMethod ipaddress)
{
SomeMethodResponse res = new SomeMethodResponse() { foo = "blabla", bar = "1" };
return res;
}
}

[XmlRoot("SomeMethodResponse")]
public class SomeMethodResponse
{
public string foo { get; set; }
public string bar { get; set; }
}

[XmlRoot("SomeMethod")]
public class SomeMethod
{
public string ipaddress { get; set; }
}


Now we can generate a proxy with the 'normal' tooling, generate a WSDL, and connect to the PERL web service. The trick is in using the SoapParameterStyle.Bare. This gives al lot more flexibility in crafting the resulting soap.

When this method fails you can go the WCF route and use the available hooks in WCF to consume the web services.

Geen opmerkingen: