SOAP issue when calling WCF service in Perl (SOAP Lite)

Using Perl (SOAP Lite), I am trying to call the wcf web service where the SOAPAction (ProcessMessage) name is different from the name of the request element (Envelope / Body / Request ) in the soap envelope body. How to specify a different name for SOAPAction and Envelope-> Body-> Request? I cannot change the web service.

Here is an example of a SOAP message that I am trying to replicate, and I appreciated the two areas that I am trying to specify / control myself.

<HttpRequest> <Method>POST</Method> <QueryString></QueryString> <WebHeaders> <Content-Length>1245</Content-Length> <Content-Type>text/xml; charset=utf-8</Content-Type> <Accept-Encoding>gzip, deflate</Accept-Encoding> <Expect>100-continue</Expect> <Host>virscwapp01f1.sdpcsf.sdp.net.nz</Host> <SOAPAction>"urn:sdp:manager:100818.ProfileScopeServiceContract.ProcessMessage"</SOAPAction> </WebHeaders> </HttpRequest> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <ActivityId CorrelationId="0d113c44-878d-40c4-bc3d-37a1ac9a693e" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000</ActivityId> <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://[hostname]/ProfileManager/100818/ProfileManager.svc</To> <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:manager:100818.ProfileScopeServiceContract.ProcessMessage</Action> </s:Header> <s:Body> <Request xmlns="urn:managerrequestmanager:100818" xmlns:a="urn:manager:requestmanager" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:Payload i:type="b:Organisation" xmlns:b="urn:manager:contract:110308"> <b:OrganisationUnitId>OrgId</b:OrganisationUnitId> <b:OrganisationDescription i:nil="true"></b:OrganisationDescription> </a:Payload> <a:ProcessingInstruction xmlns:b="urn:manager:contract:common:100818"> <b:Action>GetOrganisationById</b:Action> <b:Strategy> <b:Name i:nil="true"></b:Name> <b:Paging i:nil="true"></b:Paging> <b:SearchCriteria i:nil="true"></b:SearchCriteria> </b:Strategy> <b:Meta i:nil="true"></b:Meta> </a:ProcessingInstruction> </Request> </s:Body> </s:Envelope> 

Here is an example Perl script I am using

 #!/usr/bin/perl package main; use SOAP::Lite +trace; use LWP::UserAgent; use HTTP::Request::Common; # Variables my $url = 'http://[hostname]/ProfileManager/100818/ProfileManager.svc?wsdl'; my $url_debug = 'http://localhost:11040/Service1.svc?wsdl'; my $uri = 'urn:::profilemanager:profilemanagerrequestmanager:100818'; my $soap = SOAP::Lite -> ns( 'http://www.w3.org/2001/XMLSchema-instance', 'xsi' ) -> ns( 'urn:::profilemanager:requestmanager', 'a' ) -> ns( 'urn:::profilemanager:contract:110308', 'b' ) -> uri($uri) -> on_action( sub { join '.', 'urn:::profilemanager:requestmanager:100818.ProfileScopeServiceContract', $_[1] } ) -> proxy($url); my $method = SOAP::Data->name('ProcessMessage') ->attr({xmlns => 'urn:::profilemanager:profilemanagerrequestmanager:100818'}); my @params = ( SOAP::Data->type("b:Organisation")->name("a:Payload")->value( \SOAP::Data->value( SOAP::Data->name("b:OrganisationUnitId")->value(""), SOAP::Data->name("b:OrganisationDescription")->attr( { 'xsi:nil' => "true" } ) ) ), SOAP::Data->name("a:ProcessingInstruction")->value( \SOAP::Data->value( SOAP::Data->name("b:Action")->value("GetOrganisationById"), SOAP::Data->name("b:Strategy")->value( \SOAP::Data->value( SOAP::Data->name("b:Name")->attr( { 'xsi:nil' => "true" } ), SOAP::Data->name("b:Paging")->attr( { 'xsi:nil' => "true" } ), SOAP::Data->name("b:SearchCriteria")->attr( { 'xsi:nil' => "true" } ) ) ), SOAP::Data->name("b:Meta")->attr( { 'xsi:nil' => "true" } ) ) ) ); print $soap->call($method => @params)->result; 

Do not pay too much attention to my namespaces, as I deleted parts of them.

+4
source share
1 answer

I had to do this for SOAP :: Lite to work with WCF:

 my $serviceInterface = 'IMyWcfServiceInterface'; # Setup Network Connection my $service = SOAP::Lite ->ns( $namespace, $namespacePrefix ) ->proxy( $server, credentials => [ "$host:$port", $realm, $username => $password ] ) ->on_action( sub { my $action = sprintf( '%s$serviceInterface/%s', @_ ); print( "action: '$action'\n" ); return $action; } ); my $response = $service->MyServiceFunction() 

In your case, it seems to you that the action should be: urn:sdp:manager:100818.ProfileScopeServiceContract.ProcessMessage , so you can probably just use:

 ... ->on_action( 'urn:sdp:manager:100818.ProfileScopeServiceContract.ProcessMessage' ) ... 

Pearl pom documentation :

 on_action(callback) $client->on_action(sub { qq("$_[0]") }); 

Fired when the transport object sets the SOAPAction header for the HTTP-based call. By default, the header for the string is set, the uri # method, in which the URI is the value set by the uri method described earlier, and the method is the name of the method called. When called, the subroutine referred to (or closure, if indicated as an example) is given two arguments, uri and method, in that order.

.NET web services usually expect / as a separator for uri and method. To change the SOAP :: Lite behavior to use uri / method as the SOAPAction header, use the following code:

  $client->on_action( sub { join '/', @_ } ); 
0
source

Source: https://habr.com/ru/post/1489826/


All Articles