4

Perl (SOAP Lite) を使用して、SOAP エンベロープ ボディ内の SOAPAction 名 (ProcessMessage) が Envelope/Body/ Request要素名 (Request)と異なる wcf Web サービスを呼び出そうとしています。別の SOAPAction と Envelope->Body->Request 要素名を指定するにはどうすればよいですか? Web サービスを変更できません。

これは、私が複製しようとしている SOAP メッセージの例です。個別に指定/制御しようとしている 2 つの領域を強調しました。

<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; 

名前空間の一部を削除したので、名前空間にあまり注意を払わないでください。

4

1 に答える 1

0

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 ドキュメント:

on_action(callback)

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

トランスポート オブジェクトが HTTP ベースの呼び出しの SOAPAction ヘッダーを設定するときにトリガーされます。デフォルトでは、ヘッダーを文字列 uri#method に設定します。ここで、URI は
前述の uri メソッドによって設定された値であり、method
は呼び出されるメソッドの名前です。呼び出されると、参照されるルーチン (
例のように指定されている場合はクロージャー) には、uri と method の 2 つの引数がこの順序で与えられます。

.NET Web サービスは、通常、uri とメソッドの区切り文字として / を想定しています。uri/method を SOAPAction ヘッダーとして使用するように SOAP::Lite の動作を変更するには、次のコードを使用します。

    $client->on_action( sub { join '/', @_ } );
于 2013-11-01T16:18:21.520 に答える