Hi!
I've created some standalone SOAP server applications based on this article:http://www.digicoast.com/delphi_soap_standalone.html but I got tired of the long procedure, so I thought I make it a bit simpler, and created this unit:
unit Unit2;
interface
uses
SysUtils, Classes, Windows, Messages, Variants, Graphics, Controls, Forms, Dialogs,
WebReq, HTTPApp, WSDLPub, SOAPPasInv, SOAPHTTPPasInv, SOAPHTTPDisp, WebBrokerSOAP,
InvokeRegistry, SOAPDm, Types, OPConvert, IdHTTPWebBrokerBridge;
type
IMyService = interface(IInvokable) { Invokable interfaces must derive from IInvokable }
['{EB829A60-4B39-4EC8-A684-E4D7BA713036}'] { Methods of Invokable interface must not use the default calling convention; stdcall is recommended }
function Hello: String; stdcall;
end;
type
TMyDataModule = class(TSoapDataModule,IMyService)
private
function Hello:String; stdcall;
public
end;
type
TMyWebModule = class(TCustomWebDispatcher)
fHTTPSoapDispatcher : THTTPSoapDispatcher;
fHTTPSoapPascalInvoker : THTTPSoapPascalInvoker;
fWSDLHTMLPublish : TWSDLHTMLPublish;
procedure DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override;
end;
type TSOAPServer = class
private
fWebModule : TMyWebModule;
fWebBrokerBridge : TIdHTTPWebBrokerBridge;
public
constructor Create(AOwner: TComponent);
destructor Destroy;override;
end;
implementation
procedure TMyDataModuleCreateInstance(out obj: TObject);
begin
obj := TMyDataModule.Create(nil);
end;
{ TMyWebModule }
constructor TMyWebModule.Create(AOwner: TComponent);
begin
inherited;
OldCreateOrder := False;
with Actions.Add do begin
Default := True;
PathInfo := '/';
Name := 'DefaultHandler';
OnAction := DefaultHandlerAction;
end;
fHTTPSoapDispatcher := THTTPSoapDispatcher.Create(nil);
fHTTPSoapPascalInvoker := THTTPSoapPascalInvoker.Create(nil);
fWSDLHTMLPublish := TWSDLHTMLPublish.Create(nil);
fHTTPSoapPascalInvoker.Converter.Options := [soSendMultiRefObj, soTryAllSchema, soRootRefNodesToBody, soCacheMimeResponse, soUTF8EncodeXML];
fHTTPSoapDispatcher.WebDispatch.PathInfo := 'soap*';
fWSDLHTMLPublish.WebDispatch.MethodType := mtAny;
fWSDLHTMLPublish.WebDispatch.PathInfo := 'wsdl*';
fHTTPSoapDispatcher.Dispatcher := fHTTPSoapPascalInvoker;
end;
destructor TMyWebModule.Destroy;
begin
FreeAndNil(fHTTPSoapDispatcher);
FreeAndNil(fHTTPSoapPascalInvoker);
FreeAndNil(fWSDLHTMLPublish);
inherited;
end;
procedure TMyWebModule.DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
fWSDLHTMLPublish.ServiceInfo(Sender, Request, Response, Handled);
end;
{ TSOAPServer }
constructor TSOAPServer.Create(AOwner: TComponent);
begin
// inherited Create;
fWebModule := TMyWebModule.Create(AOwner);
InvRegistry.RegisterInterface(TypeInfo(IMyService));
InvRegistry.RegisterInvokableClass(TMyDataModule, TMyDataModuleCreateInstance);
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := TMyWebModule;
fWebBrokerBridge := TIdHTTPWebBrokerBridge.Create(nil);
fWebBrokerBridge.RegisterWebModuleClass(TMyWebModule);
fWebBrokerBridge.DefaultPort := 1029;
fWebBrokerBridge.Active := True;
end;
destructor TSOAPServer.Destroy;
begin
fWebBrokerBridge.Active := False;
FreeAndNil(fWebModule);
FreeAndNil(fWebBrokerBridge);
inherited;
end;
{ TMyDataModule }
function TMyDataModule.hello: String;
begin
Result := 'Hello!!';
end;
end.
So i have a class, which can be used like this:
//...
var serv: TSOAPServer;
//...
begin
serv := TSOAPServer.Create(Form1);
end;
When I go to the http://localhost:1029 I can see my webservice, and its "Hello" function, but when I click on the WSDL link, I can't see the generated WSDL, so there is no way to create a client for the service. What am I doing wrong?
Edited by: Peter Pinter on Mar 21, 2009 3:35 PM