Что означает ошибка синтаксического анализа XML, отправленная из TXMLTransform, когда я использую SOAP для удаленного чтения данных в клиентский набор данных через SOAP в Delphi?

Я задал еще один вопрос, связанный с SOAP. назад, который запрашивает рабочий клиент и сервер Soap для Delphi XE и выше.

Готового решения ни у кого не было, поэтому я восстановил демонстрацию эпохи 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.
     '.

Здесь показан стек вызовов исключений на стороне сервера для модуля данных Indy 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-ответ. Это имело бы смысл для меня, если бы ничего не работало, и URL-адрес HTTP, к которому мы обращаемся, не работает. 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>

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


person Warren P    schedule 22.03.2012    source источник
comment
Я бы использовал прокси (Fiddler) и сравнил бы запросы/ответы рабочей (WAD) и нерабочей версии. URL-адрес может быть рабочим, но браузер отправляет HTTP-запросы GET, в то время как SOAP обычно также использует POST.   -  person mjn    schedule 23.03.2012


Ответы (1)


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

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

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

Урок выучен; При создании сервера SOAP рассмотрите обработку ошибок конфигурации и обнаружение неустранимых ошибок в качестве начальной задачи перед первым сеансом сервера SOAP.

person Warren P    schedule 27.03.2012