2013-07-05 44 views
4

使用Perl(SOAP Lite)時,我試圖調用一個wcf web服務,其中SOAPAction名稱(ProcessMessage)與信封/正文/ 請求元素名稱(Request)在肥皂信封體內。如何指定一個不同的SOAPAction和Envelope-> Body-> Request元素名稱?我無法更改Web服務。使用Perl(SOAP Lite)調用WCF服務時的SOAP操作問題

下面是我嘗試複製的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> 

這裏是我使用

#!/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腳本的例子。

+0

我相信有人在這裏回答我的問題,但由於我是新來使用Perl我不明白回答。 [link] http://code.activestate.com/lists/perl-xml/8922/ [鏈接] –

+0

好吧我自己找出解決方案 –

+0

作爲參考,如果遇到其他人遇到問題,共享解決方案將是一件好事。一樣的問題。 –

回答

0

我不得不這樣做是爲了使SOAP ::精簡版工作,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方法設置的值,方法是調用的方法
的名稱。當被調用時,引用的例程(或者關閉,如果在
例子中指定)按照該順序給出兩個參數uri和method。

.NET Web服務通常期望/作爲uri和方法的分隔符。要更改SOAP ::精簡版的 行爲,以便使用URI /方法SOAPAction頭,使用如下代碼:

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