我正在做一个电子发票项目,它使用WSDL肥皂连接到服务下一个链接Link Wsdl Service
所以我使用Delphi的 WSDL Importer 来生成要连接的类。
我使用该服务的代码
procedure TForm1.Button1Click(Sender: TObject);
var
tBillServ : billService;
tSendB : sendBill;
ByteA : TByteDynArray;
tSendBResp: sendBillResponse;
begin
tSendB:=sendBill.Create;
tSendBResp:=sendBillResponse.Create;
tSendB.fileName:='Demo.zip';
SetLength(ByteA,2);
ByteA[0]:=10;
ByteA[1]:=20;
tSendB.contentFile:=ByteA;
tSendBResp:=tBillServ.sendBill(tSendB);
end;
我提交的数据只是针对来自服务器的响应的试用版,但是我出现了一条错误消息,正在查找但找不到任何可以帮助我的内容。
如果需要WS-Security连接来更改使用WSDL Importer生成的类的编程?
我遇到了大麻烦,因为他们无法找到解决问题的方法。
我希望我可以提供帮助,对不起我的英语,我使用谷歌翻译
答案 0 :(得分:1)
上周我遇到了同样的问题。我正在使用Delphi 2010。
首先:我无法设法实现功能齐全的TSOAPHeader后代。我能达到的最远的是要么得到" wsse:"标头节点中的前缀或正确声明wsse命名空间。但它们是相互排斥的:(。
我打赌你试图调用你的webservice方法时得到以下消息:"没有WS-Security标题"。对吗?
添加WS-Security标头的实际工作方式是构建完整的标头节点并在OnBeforeExecute()中添加以下代码:
// Load a copy of the XML in a separate TXMLDocument
XMLDocument.LoadFromStream(SOAPRequest);<br>
{ Build your complete proper WS-Security header node here)<br>
// Insert the header<br>
XMLDocument.DocumentElement.ChildNodes.Insert(0, SoapHeader);<br>
// THIS LINE IS MANDATORY, AS WE WISH TO OVERWITE THE REQUEST, NOT APPEND TO IT !!!<br>
SOAPRequest.Seek(0, soFromBeginning);<br>
// Overwrite the request<br>
XMLDocument.SaveToStream(SOAPRequest);
然后,释放你的XMLDocument,进行清理等等......它应该可以工作。
答案 1 :(得分:0)
我通过创建此功能解决了这个问题
function GetbillService(UseWSDL: Boolean; Addr: string;var HTTPRIO: THTTPRIO): billService;
const
defWSDL = 'https://www.sunat.gob.pe:443/ol-ti-itcpgem-beta/billService?wsdl';
defURL = 'https://www.sunat.gob.pe:443/ol-ti-itcpgem-beta/billService';
defSvc = 'billService';
defPrt = 'BillServicePort';
var
RIO: THTTPRIO;
begin
if (Addr = '') then
begin
if UseWSDL then
Addr := defWSDL
else
Addr := defURL;
end;
if HTTPRIO = nil then
RIO := THTTPRIO.Create(nil)
else
RIO := HTTPRIO;
try
Result := (RIO as billService);
if UseWSDL then
begin
RIO.WSDLLocation := Addr;
RIO.Service := defSvc;
RIO.Port := defPrt;
end else
RIO.URL := Addr;
finally
if (Result = nil) and (HTTPRIO = nil) then
RIO.Free;
end;
end;
我以这种方式使用它
tBillServ:=GetbillService(True,'',HTTPRIO1);
tSendB:=sendBill.Create;
tSendBResp:=sendBillResponse.Create;
tSendB.fileName:='20100066603-01-F001-1.ZIP';
tSendB.contentFile:=FIleToByteArray('D:\E-Billing\20100066603-01-F001-1.ZIP');
tSendBResp:=tBillServ.sendBill(tSendB);
建立连接但似乎安全标头不正确 需要具备以下特点
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body xmlns:NS1="http://service.sunat.gob.pe" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="urn:billService1"><NS1:sendBill><parameters href="#1"/></NS1:sendBill><NS2:sendBill id="1" xsi:type="NS2:sendBill"><fileName xsi:type="xsd:string">20100066603-01-F001-1.ZIP</fileName><contentFile xsi:type="xsd:base64Binary">UEsDBBQA.....DAwNBgAAAAAB
AAEAawAAAD0MAAAAAA==</contentFile></NS2:sendBill></SOAP-ENV:Body></SOAP-ENV:Envelope>
但它似乎是
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<sendBill xmlns="http://service.sunat.gob.pe">
<parameters>
<fileName>20100066603-01-F001-1.ZIP</fileName>
<contentFile>UEsDBB.....NjY2MDMtA==</contentFile>
</parameters></sendBill></SOAP-ENV:Body></SOAP-ENV:Envelope>
我尝试使用正确的参数手动发送xml,但即便如此,我得到的安全标头错误
procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: string;
SOAPRequest: TStream);
var
Str:String;
outs:TStream;
begin
Str:= {Code XML};
outs:=TStringStream.Create(Str);
SOAPRequest:=outs;
end;
查看有关添加UsernameToken的WSSE.pas的信息,但我的实现不明确