Re: Trying to get SOAP_Attachment to Delphi

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Blake,

I ran into the same problem. I've tried to transfer binary data with Soap
Attachments, but it simply wouldn't work. Also the documentation on
receiving attachments (for a soap server) is quite small: nothing!

Then I found this page: http://www.agnisoft.com/white_papers/SOAP2.asp

Maybe the same method would work with PEAR::SOAP <=> Delphi, and it did!
First I tried to transfer it with base64Binary types, but this woudn't work.
I received the data from the service, but Delphi could not understand it and
returned a 0 byte file.
Then I tried to pass it as a string (since PHP coded the file as a base64
string...), and it works!

Below you can see the sourcecode of the PEAR::SOAP server and the Delphi
client app. It is not complete - for testing purposes only - but the
download method works... With this example you should be able to create your
own binary transfer SOAP service with PHP and Delphi.

===[PHP Sourcecode]===
<?php
/**
 * Test SOAP Server
 */

ini_set( 'include_path', '.;D:\httpdocs\codebase\PEAR' );

class TestSoapServer {
 var $__dispatch_map = array(
     'downloadFile' => array(
         'in' => array( 'filename' => 'string' ),
         'out' => array( 'base64file' => 'string' )
  ),
  'uploadFile' => array(
      'in' => array( 'filename' => 'string', 'base64file' => 'string' ),
      'out' => array( 'successful' => 'boolean' )
  )
 );

 function downloadFile( $filename ){
  return base64_encode( file_get_contents('test.jpg') );
 }

 function uploadFile( $filename, $file ){
     return false;
 }
}

require_once('SOAP/Server.php');

$server =& new SOAP_Server();
//$server->_auto_translation = true;

$soapclass =& new TestSoapServer();
$server->addObjectMap($soapclass,'urn:TestSoapServer');

if( isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] ==
'POST') {
    $server->service( $HTTP_RAW_POST_DATA );
}else{
    require_once( 'SOAP/Disco.php' );
    header( "Content-type: text/xml" );
    $disco = new SOAP_DISCO_Server( $server, 'TestSoapServer' );
    echo $disco->getWSDL();
    exit;
}
?>
===[PHP Sourcecode]===

As you can see, I've hardcoded the server class methods, so you have to
change those...

===[Delphi(7) Sourcecode]===
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, InvokeRegistry, StdCtrls, ExtCtrls, Rio, SOAPHTTPClient, Types,
  IdBaseComponent, IdCoder, IdCoder3to4, IdCoderMIME;

type
  TForm1 = class(TForm)
    Button1: TButton;
    SoapServ: THTTPRIO;
    Label1: TLabel;
    Base64d: TIdDecoderMIME;
    procedure Button1Click(Sender: TObject);
    procedure SoapServHTTPWebNode1ReceivingData(Read, Total: Integer);
  private
    { Private declarations }
    Amount: integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  transfer;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Mem: TMemoryStream;
begin
  Amount := 0;
  Mem := TMemoryStream.Create;
  try
    Base64d.DecodeToStream( WideCharToString(PWideChar((SoapServ as
TestSoapServerPort).downloadFile('bla'))), Mem);
    Mem.SaveToFile('test2.jpg');
  finally
    Mem.Free;
  end;
end;

procedure TForm1.SoapServHTTPWebNode1ReceivingData(Read, Total: Integer);
begin
  Inc(Amount, Read);
  Label1.Caption := IntToStr(Amount);
  Application.ProcessMessages;
end;

end.
===[Delphi(7) Sourcecode]===

The base64d object is a base64decode component from Indy. The form contains
a simple download button, a text label (shows the bytes transfered) and the
base64decode component. 'tranfer' is the service interface created by the
WSDL wizard in Delphi.

Keep in mind I am a beginner with Delphi programming, so my code could
contain bugs...

I've transfered succesful two JPEG images, one about 1.1MB.

Hope this helps ;).

Bart Verkoeijen
www.oikoyama.net

"Raltgaither@Yahoo.Com" <raltgaither@yahoo.com> schreef in bericht
20040213220232.94648.qmail@pb1.pair.com">news:20040213220232.94648.qmail@pb1.pair.com...
> Hi, All.
>
> I've read the messages here about sending Attachments to Delphi, and
> I've made Dave's "adjustments" to the appropriate files, but I still
> can't get this thing to work.
>
> In Delphi I'm looking for the return value to be "TSoapAttachment". It
> seems to want to be a "TByteDynArray". Here's my server code to generate
> the wsdl:
>
>      $this->__dispatch_map['getXML'] = array(
>                'in'=>array(),
>                'out'=>array('response' => 'base64Binary')
>                );
>
> If I change 'base64Binary' to 'TSoapAttachment' (cheating, I know),
> Delphi presents the correct return value but I get an error when I click
> the button to load the file.
>
> Here's my actual method:
>
> function getXML(){
>   $cm_path = "/home/httpd/httpdocs/services/";
>   $cm_file = "test.xml";
>
>   if (file_exists($cm_path.$cm_file)){
>    return new
> SOAP_Attachment('Response','application/binary',$cm_path.$cm_file);
>    }
>   else {
>    return new SOAP_Value('return', 'application/binary', false);
>    }
> }
>
>
> Which part am I screwing up? If it helps, here's my client side in Delphi:
>
> procedure TForm1.Button1Click(Sender: TObject);
> var
>     Intrf : CV3_Web_ServicePort;
>     xmlDoc : TXMLDocument;
>     myStream : TStream;
>     myAttachment : TSOAPAttachment;
>
> begin
>     Intrf := GetCV3_Web_ServicePort(False, '');
>     try
>        myAttachment := Intrf.getXML;
>     except
>        on E : Exception do
>           ShowMessage(E.Message);
>     end;
>     myStream := myAttachment.SourceStream;
>     xmlDoc := TXMLDocument.Create(nil);
>     xmlDoc.LoadFromStream(myStream);
>     ListBox1.Items.AddStrings(xmlDoc.XML);
> end;
>
>
> Any help is much, much appreciated!
>
> Thanks,
> Blake <raltgaither@yahoo.com>

-- 
PHP Soap Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [Kernel Newbies]     [PHP Database]     [Yosemite]

  Powered by Linux