在 Perl (SOAP Lite) 中调用 WCF 服务时的 SOAP 操作问题
Posted
技术标签:
【中文标题】在 Perl (SOAP Lite) 中调用 WCF 服务时的 SOAP 操作问题【英文标题】:SOAP Action issue when calling WCF Service in Perl (SOAP Lite) 【发布时间】:2013-07-03 01:43:24 【问题描述】:使用 Perl (SOAP Lite),我正在尝试调用 wcf Web 服务,其中 SOAPAction 名称 (ProcessMessage) 与肥皂中的 Envelope/Body/Request 元素名称 (Request) 不同信封体。如何指定不同的 SOAPAction 和 Envelope->Body->Request 元素名称?我无法更改网络服务。
这是我尝试复制的 SOAP 消息的示例,我强调了我尝试独立指定/控制的两个区域。
<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>
这是我正在使用的 Perl 脚本示例
#!/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;
不要过多关注我的命名空间,因为我已经删除了其中的一部分。
【问题讨论】:
我相信有人在这里回答了我的问题,但由于我是 Perl 新手,所以我不明白答案。 [链接]code.activestate.com/lists/perl-xml/8922[链接] 好的,我自己制定了解决方案 作为参考,最好分享解决方案,以防其他人遇到同样的问题。 【参考方案1】:我必须这样做才能使 SOAP::Lite 与 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()
在您的情况下,您似乎希望操作是:urn:sdp:manager:100818.ProfileScopeServiceContract.ProcessMessage
,所以您应该可以只使用:
...
->on_action( 'urn:sdp:manager:100818.ProfileScopeServiceContract.ProcessMessage' )
...
Perl pom documentation:
on_action(callback)
$client->on_action(sub qq("$_[0]") );
当传输对象设置基于 HTTP 的 SOAPAction 标头时触发 称呼。默认情况下将标头设置为字符串 uri#method,其中 URI 是 前面介绍的uri方法设置的值,method是方法的名字 被调用。调用时,引用的例程(或闭包,如果指定为 in 这个例子)按顺序给出了两个参数,uri和method。
.NET Web 服务通常期望 / 作为 uri 和方法的分隔符。改变 SOAP::Lite 的 使用 uri/method 作为 SOAPAction 标头的行为,请使用以下代码:
$client->on_action( sub join '/', @_ );
【讨论】:
以上是关于在 Perl (SOAP Lite) 中调用 WCF 服务时的 SOAP 操作问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Perl 5 中保存通过 MIME::Lite 发送的邮件的备份?