2010-11-11 2 views
10

Я импортировал WSDL и использовал его для отправки запроса SOAP. Это выглядит следующим образом:Удаление пространства имен из запроса SOAP

<?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> 
     <Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
      <ContractdocumentIn> 
       <AL> 
       ...More XML... 

Проблема заключается в xmlns="urn:xx.WSDL.xxxxxWebService" часть в элементе Calculate. Веб-служба не может этого принять. Веб-сервис не любит пространства имен, как это ...
Использования SoapUI Я нашел этот запрос работать нормально:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:col="http://example.com.service.xxx/"> 
    <SOAP-ENV:Body> 
     <col:Calculate> 
      <ContractdocumentIn> 
       <AL> 
        ...More XML... 

Итак, как изменить запрос от первого ко второй версии? (Без использования грязных трюков!)
(Re-импортирование не является проблемой, если это приведет в надлежащий формат запроса.)




снова: нет подвохов не допускается, как взлом потока запроса, чтобы изменить его !


И пока я полностью не проверил это, кажется, что C#/VS2010 и Delphi 2010 также не могут использовать веб-сервис, который я пытаюсь вызвать. Веб-сервис, который, кажется, написан на Java. SoapUI записывается на Java, поэтому у нас есть клиент Java, который разговаривает с сервисом Java, который, похоже, работает нормально. Но любой другой клиент?
В любом случае, время добавить еще два тега: «Java», так как это Java-сервис и «vs2010», потому что .NET также не любит эту услугу.
И я собирался написать обертку вокруг этой службы в .NET, надеясь, что это сработает ... Это не так. Так что это очень серьезный недостаток, возможно, недостаток Java ...

+0

Успехов. Мне приходилось прибегать к грязным трюкам. –

+0

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

+2

Код SOAP позволяет вам проверять отправляемый XML и изменять его, если вам нужно. Он явно поддерживает ручную манипуляцию. И код будет там - ничего «грязного» о манипуляции после сборки. Может быть, не так хорошо, как автоматический, но никто не должен беспокоиться об этом. – mj2008

ответ

14

Если служба ожидает:

<col:Calculate> 
    <ContractdocumentIn> 
     <AL> 

и Delphi SOAP отправляет ...

<Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
     <ContractdocumentIn> 
      <AL> 

... проблема в том, что ContractdocumentIn не является безусловным элементом и (до Delphi XE) Delphi SOAP не поддерживал неквалифицированные элементы, которые являются элементами верхнего уровня операции. Элементы верхнего уровня являются параметрами функции, и нигде не следует хранить факт, что базовый элемент должен быть неквалифицирован; для элементов, которые отображаются в свойствах, мы используем индекс свойства, чтобы сохранить флаг IS_UNQL.

BTW, нет необходимости использовать префикс. Служба будет (должна) также принимает:

<Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
     <ContractdocumentIn xmlns=""> 
      <AL> 

Последнее более многословные, но это эквивалентно случаю приставки.

В Delphi XE импортер сохраняет в стороне тот факт, что конкретный параметр сопоставляется с неквалифицированным элементом, и среда выполнения воздействует на эту информацию. Я отправил патчи, основанные на реализации XE для D2010 и D2007 в телеконференции, когда она пришла в потоке недавно:

https://forums.embarcadero.com/thread.jspa?threadID=43057

Если кому-то нужен доступ к ним (они были в области вложений, но может прокрутите прочь), напишите мне, и я сделаю их доступными. [Bbabet на Embarcadero точка ком]

Приветствия,

Брюно

+1

Хорошее объяснение! Благодарю. Я использую D2005 с плагинами D2007 для библиотек SOAP. Как вы думаете, ваши исправления для патчей D2007 будут работать для меня? –

+4

Да, должно. Патч, который я опубликовал, находится здесь: https://forums.embarcadero.com/thread.jspa?messageID=290788 – BruneauB

+0

Если у вас возникают проблемы, пожалуйста, укажите мне (или напишите мне) WSDL, и я буду исследовать. Ура! – BruneauB

8

OMG! Было много кофе и много разврата сна, но мне удалось решить мою проблему! Это также разумно просто ...
Сначала я импортирую WSDL, как и ожидалось. Это создаст несколько классов TRemotable. Затем для каждого TRemotable, которому требуется другое пространство имен, я переопределяю метод ObjectToSOAP()! (А включают XMLIntf к источнику WSDL.) В моем случае с кодом, как это для нескольких типов remotable:

function AL2.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter: IObjConverter; const NodeName, NodeNamespace, ChildNamespace: InvString; ObjConvOpts: TObjectConvertOptions; out RefID: InvString): IXMLNode; 
begin 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, NodeName, '', '', ObjConvOpts, RefID); 
end; 

Который работал в Delphi XE. В Delphi 2007 я должен был использовать блоки XMLIntf и XMLDoc плюс этот код на тип входа:

function ContractdocumentInType.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter: IObjConverter; const Name, URI: InvString; ObjConvOpts: TObjectConvertOptions; out RefID: InvString): IXMLNode; 

    procedure AlterChildren(Child: IXMLNode); 
    var 
    I: Integer; 
    begin 
    if (Child.NodeType = ntElement) then Child.SetAttributeNS('xmlns', '', ''); 
    for I := 0 to Pred(Child.ChildNodes.Count) do 
     AlterChildren(Child.ChildNodes[I]); 
    end; 

begin 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, Name, '', ObjConvOpts, RefID); 
    AlterChildren(Result); 
end; 

Это хак, на мой взгляд. Но это не очень грязно. Это немного экспериментирует, захватывая SOAP-запросы и ответы, проверяя их содержимое и проверяя, использует ли он правильные пространства имен. К сожалению, Delphi XE делает гораздо лучше в этом, чем Delphi 2007.

Тем не менее, я продолжаю этот Q открыт для любых лучших решений ...


Btw, чтобы добавить col: к выходу, Мне также пришлось изменить эту строку в WSDL RemClassRegistry.RegisterXSClass(Calculate, 'http://colan.ogconnect.service.wzp/', 'Calculate'); на следующее: RemClassRegistry.RegisterXSClass(Calculate, 'http://colan.ogconnect.service.wzp/', 'cal:Calculate');. Затем результат будет <cal:Calculate xmlns:cal="http://example.webservice/">. Однако нужно еще кое-что сделать: переместить xmlns:cal в заголовок xml. Но как сейчас, это работает для меня.


Еще одно замечание: для WSDL я использовал следующие настройки: «Один Outparam является возвращение», «Расслабиться буквенные Params», «Создать деструкторов», «Предупреждение комментарии», «испускают литералы», 'Отобразить строку в ширину'. Другие варианты: «Генерировать подробные сведения о типах и интерфейсах», «Игнорировать типы портов с HTTP-привязками», «Проверять элементы перечисления», «Импортировать типы ошибок», «Импортировать типы заголовков», «Включенные процессы и импортированные схемы», «Создать class alias как типы классов ',' Allow Out parameters 'и' Process nillable and optional elements '. испускать литерал типов был практичным, потому что он генерирует класс вокруг одного метода, который я вызывал. К сожалению, это тоже не поможет, хотя класс поможет вам изменить запрос SOAP на верхнем уровне в конверте, переопределив метод ObjectToSOAP().
Создание самого конверта находится в блоке SOAPEnv и используется в блоке OPToSOAPDomConv. К сожалению, я не нашел простой способ доступа к самому конверту, чтобы изменить заголовок, чтобы добавить это дополнительное пространство имен. Опять же, я могу переопределить класс TSOAPDomConv своей собственной версией, которая добавит дополнительное пространство имен. Но теперь код работает для меня, и, как сказал мой отец, когда он научил меня программировать: никогда не исправлять ничего, что не сломалось.

+0

Выглядит многообещающе - я собираюсь дать ему вихрь. Это может сэкономить много времени/боли при большом проекте, поэтому я счастлив внести в дискуссионные пункты. –

+0

Действительно ли это дает вам результат следующим образом:

+0

Я думаю, что это может дать мне хорошее место, чтобы подключиться, но мне, возможно, потребуется больше работать в функции AlterChildren. –

Смежные вопросы