2012-03-22 3 views
2

Я спросил another SOAP related question некоторое время назад, в котором запрашивается рабочий Soap Client и Server для Delphi XE и выше.Что означает ошибка синтаксического анализа XML, отправленная из TXMLTransform, когда я использую SOAP для удаленного чтения данных в clientdataset через SOAP в Delphi?

Никто не имел решения из коробки, поэтому я вернул демоверсию Delphi 2007 в рабочее состояние для Delphi XE и XE2. У меня работает демонстрация, и у меня есть сервер на основе форм INDY VCL (автономный HTTP-сервер, работающий на Indy) с сервером Soap. Две части демоверсии сервера - это «пользовательский метод» (обычный вызов функции мыла) и «удаленный набор данных». Это удаленный набор данных, что я не могу работать.

ошибка, что у меня есть в виде клиента, когда я установил клиентский набор данных активен, сервер отправляет исключение, когда я делаю эту строку в демонстрационном клиенте:

ClientDataSet1.Open; 

Это, в свою очередь, идет вниз в DBClient.pas код, TDataSet.OpenCursor вызывает DoGetRecords, который пытается читать из ProviderName = 'XMLTransformProvider1', этого RIO вызов:

Result := AppServer.AS_GetRecords(ProviderName, Count, RecsOut, Options, 
    CommandText, Params, OwnerData); 
    // ProviderName = 'XMLTransformProvider1', Count = -1, 
    // CommandText = '', Params = NULL, OwnerData = Unassigned 

Это взрывает с этим исключением, показанным в типичном MessageBox форма:

`ERemotableException: XML Parse error...`. 
    ERemotableException 
    'XML Parse Error: 
    Reason: The system cannot locate the object specified. 
    '. 

на стороне сервера стек вызовов исключение для модуля данных Soap Инди показано здесь:

xmlutil.DocParseError(TMSDOMDocument($292C994) as IDOMDocument) 
xmlutil.LoadDocFromFile(???) 
Xmlxform.TXMLTransform.GetData 
Xmlxform.TXMLTransformProvider.InternalGetRecords(???,???,[grMetaData],'',Null) 
Provider.TCustomProvider.DoGetRecords(-1,0,1,'',Null,Null) 
Provider.TCustomProvider.GetRecords(???,0,1,'',Null,Null) 
SOAPDm.TSoapDataModule.GetRecords('XMLTransformProvider1',-1,0,1,'',Null,Null) 
SOAPDm.TSoapDataModule.SAS_GetRecords('XMLTransformProvider1',-1,0,1,'',Null,Null) 
Invoker.TInterfaceInvoker.Invoke(???,('IDataMod', 'DataMod_U', (('', ccReg, 0, 0, nil, nil,(), False), ('', ccReg, 0, 0, nil, nil,(), False), ('', ccReg, 0, 0, nil, nil,(), False), ('SAS_ApplyUpdates', ccStdCall, 3, 5, $401314, $628D50, (([pfConst], 'ProviderName', $4012DC), ([pfReference], 'Delta', $401314), ([], 'MaxErrors', $4010A0), ([pfOut], 'ErrorCount', $4010A0), ([pfVar,pfReference], 'OwnerData', $401314), ([], '', nil)), True), ('SAS_GetRecords', ccStdCall, 4, 7, $401314, $628D50, (([pfConst], 'ProviderName', $4012DC), ([], 'Count', $4010A0), ([pfOut], 'RecsOut', $4010A0), ([], 'Options', $4010A0), ([pfConst], 'CommandText', $4012DC), ([pfVar,pfReference], 'Params', $401314), ([pfVar,pfReference], 'OwnerData', $401314), ([], '', nil)), True), ('SAS_DataRequest', ccStdCall, 5, 2, $401314, $628D50, (([pfConst], 'ProviderName', $4012DC), ([pfReference], 'Data', $401314), ([], '', nil)), True), ('SAS_GetProviderNames', ccStdCall, 6, 0, $40BC38, $628D50, (([], '', nil)), True), ('SAS_GetParams', ccStdCall, 7, 2, $401314, $628D50, (([pfConst], 'ProviderName', $4012DC), ([pfVar,pfReference], 'OwnerData', $401314), ([], '', nil)), True), ('SAS_RowRequest', ccStdCall, 8, 4, $401314, $628D50, (([pfConst], 'ProviderName', $4012DC), ([pfReference], 'Row', $401314), ([], 'RequestType', $4010A0), ([pfVar,pfReference], 'OwnerData', $401314), ([], '', nil)), True), ('SAS_Execute', ccStdCall, 9, 4, nil, $628D50, (([pfConst], 'ProviderName', $4012DC), ([pfConst], 'CommandText', $4012DC), ([pfVar,pfReference], 'Params', $401314), ([pfVar,pfReference], 'OwnerData', $401314), ([], '', nil)), True), ('CustomMethod', ccStdCall, 10, 0, $4012CC, $62E668, (([], '', nil)), True)), (45872836, 16917, 16768, (153, 166, 192, 149, 84, 207, 120, 216)), $62E668, $628D50, 10),4,$2942270) 
SOAPPasInv.TSoapPascalInvoker.Invoke(???,???,'',$28F3700,$28F36A0,???) 
SOAPHTTPPasInv.THTTPSoapPascalInvoker.DispatchSOAP('/SOAPDMServerWAD.Sample/soap/IDataMod',???,$28F3700,$28F36A0,btSoap) 
WebBrokerSOAP.THTTPSoapDispatcher.DispatchRequest(???,???,$29421C8) 
HTTPApp.DispatchHandler($28E4140,THTTPSoapDispatcher($291687C) as IWebDispatch,$290FEA0,$29421C8,False) 
HTTPApp.TCustomWebDispatcher.DispatchAction($290FEA0,$29421C8) 
HTTPApp.TCustomWebDispatcher.HandleRequest(???,???) 
HTTPApp.TDefaultWebAppServices.InvokeDispatcher 
HTTPApp.TDefaultWebAppServices.HandleRequest 
WebReq.TWebRequestHandler.HandleRequest($290FEA0,$29421C8) 
IdHTTPWebBrokerBridge.TIdHTTPWebBrokerBridgeRequestHandler.Run(???,$28851B0,???) 
IdHTTPWebBrokerBridge.TIdHTTPWebBrokerBridge.DoCommandGet(???,???,???) 
IdCustomHTTPServer.TIdCustomHTTPServer.DoExecute($293AB30) 
IdContext.TIdContext.Run 
IdTask.TIdTask.DoRun 
IdThread.TIdThreadWithTask.Run 
IdThread.TIdThread.Execute 
Classes.ThreadProc($28A1FE0) 

То, что я считаю, что происходит, что мы получаем пустой ответ HTTP. Это будет иметь для меня смысл, если ничего не получится, и HTTP-url, к которому мы обращаемся, не работает. Мы доступ к URL есть, и доступна через веб-браузер:

http://localhost:8088/?intf=IDataMod 

XML, который возвращается клиенту, который вызвал сообщение об ошибке выглядит следующим образом:

<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> 
    <SOAP-ENV:Fault> 
    <faultcode>SOAP-ENV:Server</faultcode> 
    <faultstring>XML Parse Error:'#$D#$A#$D#$A'Reason: The system cannot locate the object specified.'#$D#$A#$D#$A#$D#$A'</faultstring> 
    <faultactor/> 
</SOAP-ENV:Fault> 
</SOAP-ENV:Body></SOAP-ENV:Envelope> 

Мой вопрос is: Что действительно означает эта ошибка SOAP и почему это происходит, и как вы ее исправить?

+1

Я бы использовал прокси (Fiddler) и сравнивал запросы/репсоны рабочей (WAD) и нерабочих версий. URL-адрес может работать, но браузер отправляет HTTP-запросы GET, в то время как SOAP обычно также использует POST. – mjn

ответ

1

В этом случае это означает, что клиент получил уведомление о том, что исключение произошло на стороне сервера. Поскольку исключение на стороне сервера было вызвано проблемой с демо-кодом, решение заключается в ремонте демонстрационного сервера, чтобы он работал правильно.

В случае сервера SOAP, поставляемого с Delphi 2007, в папке с образцами SoapDataModule проблема заключается в том, что у него нет проверки ошибок; если он не загружает образцы данных XML (поскольку папка данных перемещена или отсутствует), тогда она взрывается с необработанным исключением на стороне сервера.

SOAP обладает прекрасным свойством автоматизировать вашу работу за вас; Клиент получает уведомление о том, что мы получили вызов мыла, и мы возвращаем исключение soap вместо реального ответа. Нельзя обвинять SOAP здесь, и Delphi SOAP RTL на самом деле очень удобен в использовании. Но основной момент, который нужно убрать, заключается в том, что разработчик службы мыла должен выполнить некоторую проверку работоспособности на мыльном сервере, когда он запущен, чтобы можно было устранить ошибки, прежде чем они должны были стать фатальными для запроса SOAP.

Извлеченный урок; Когда вы создаете SOAP-сервер, рассмотрите конфигурацию-обработку ошибок и обнаружение фатальной ошибки в качестве задачи запуска перед первым сеансом сервера SOAP.