Delphi конверт SOAP и WCF

Я работаю над системой, которая обеспечивает интерфейс мыла. Одна из систем, которые собираются использовать интерфейс, кодируется в Delphi 7. Веб-сервис разрабатывается с WCF, основной привязкой http, SOAP 1.1.

Если я использую SOAP UI (JAVA), сервис работает правильно. Но Delphi, кажется, делает специальные вещи здесь ;)

Это - то, как сообщение похоже в SOAP на UI:


   
   
      
         
          
            ?
         
      
   

Я не разработчик Дельфи, но я разработал простой тестовый клиент для наблюдения то, что идет не так, как надо. Это, что Delphi отправляет как конверт SOAP.


  
    
      
    
    
      253
    
  

WCF бросает ошибку, которая находится на немецком языке... ;)

Десять кубометров Es wurde Endelement "Тело" aus Пространство имен "http://schemas.xmlsoap.org/soap/envelope/" erwartet. Gefunden wurde "Пространство имен Элемента "http://services.xxx.de/xxx" "NS2:GetCustomerRequest" aus". Zeile 1, Положение 599.

Средства что-то как

Тело ожидалось. Но вместо этого Элемент "NS2:GetCustomerReques" был найден.

Теперь мои вопросы: я могу так или иначе изменить способ, которым Delphi создает конверт? Или пути состоят в том, чтобы заставить WCF работать с такими форматами сообщения? Любая справка значительно ценится!

12
задан Chris 18 March 2010 в 20:12
поделиться

3 ответа

Вопреки тому, что некоторые здесь намекают, Delphi не отправляет недействительный SOAP, а просто отправляет RPC / Encoded SOAP. Это очень легко узнать по всем атрибутам xsi: type . RPC / Encoded несовместим с WS-I, но является действующим протоколом SOAP.

WCF по умолчанию использует формат SOAP Document / Literal / Wrapped , который Delphi 7 вообще не может обрабатывать на стороне сервера, и вам необходимо внести некоторые изменения на стороне клиента.

Простейшее решение - просто указать Delphi использовать стиль Document / Literal. Это можно сделать, включив soLiteralParams в THttpRio.Converter.Options . Это говорит Delphi не «раскручивать» параметры, как вы видите. Аспект «Документ» - это то, что импортер Delphi WSDL обычно может определить, поэтому вам не следует об этом беспокоиться.

Другое решение - указать службе WCF использовать стиль RPC / Encoded, что можно сделать, добавив в службу следующие атрибуты:

[ServiceContract]
[XmlSerializerFormat(Style = OperationFormatStyle.Rpc,
    Use = OperationFormatUse.Encoded)]
public interface IMyService
{
    // etc.
}

Второй вариант не рекомендуется, потому что, как я упоминал ранее, RPC / Encoded не совместим с WS-I, но, тем не менее, большинство наборов инструментов SOAP распознают его, поэтому я перечисляю его здесь как возможный.

17
ответ дан 2 December 2019 в 18:18
поделиться

Фреймворки Delphi и Java используют разное пространство имен. Один из способов сделать их совместимыми - перехватить необработанный xml и изменить все "NS2" на то, что ожидает десериализатор

Будьте здоровы

-1
ответ дан 2 December 2019 в 18:18
поделиться

Я только что сделал одно из них, и в итоге я получил серию вызовов stringreplace, чтобы изменить вывод XML, чтобы удалить встроенные пространства имен и сделать его похожим на формат SoapUI. Да, для этого требуется много ручного взлома.

Пример:

После создания RIO вызовите собственную процедуру BeforeExecute:

...
 EEUPSERTRIO.OnBeforeExecute := self.RIO_BeforeExecute;
...

procedure TMyWrapper.RIO_BeforeExecute(const MethodName: string; var SOAPRequest: WideString);
{
Since Delphi isn't very good at SOAP, we need to fix the request so that the namespaces are correct.
Basically, you take what Delphi gives you and try it in SoapUI.
If yours doesn't work and SoapUI's version does, make yours look like theirs.
}

... Теперь удалите встроенные пространства имен:

SOAPRequest := StringReplace(SOAPRequest,' xmlns:NS1="http://services.xxx.de/xxx"','',[rfReplaceAll,rfIgnoreCase]);

... {{1} } Многие из них.

Затем вы замените заголовок мыла заголовком, который содержит нужные вам пространства имен.

SOAPRequest := StringReplace(SOAPRequest,'xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"','xmlns:ns1="http://services.xyzcorp.com/xyz/EnterpriseEmployeeService_1_0" '+'xmlns:ns1="http://schemas.xyzcorp.com/TLOIntegration_HRO_Preview/TLOIntegration_1_0" ',[]);

Затем вы можете повторно внедрить хорошие:

  ReplaceTag(SOAPRequest,'<metaData>','ns1:');
  ReplaceTag(SOAPRequest,'<trackingId>','ns1:');
  ReplaceTag(SOAPRequest,'<srcSystem>','ns1:');

Наконец, вы можете легко захватить вывод Delphi, повторно используя WSDL с помощью SoapUI и разместив на нем mockservice. Затем укажите свое приложение на него как на конечную точку, и оно зафиксирует вывод.
Или вы можете использовать Fiddler в качестве прокси для захвата запросов.

4
ответ дан 2 December 2019 в 18:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: