Отправка Soap обрабатывается вручную — XmlNode: типы узлов и атрибуты доступны только для чтения

#c# #soap #xmlnode

#c# #soap #xmlnode

Вопрос:

Я должен вызвать веб-сервис, но создать xml вручную. Я выбрал System.Xml для этого, но это причиняет мне много боли.

Каждое известное мне мыло состоит из 3 частей:

  • Объявление XmlDeclaration
  • Заголовок конверта или SOAP-ENV:Envelope
  • Тело конверта или SOAP-ENV:Body

Дело в том, что мой XML-документ может содержать только один корневой элемент. (Не знаю почему) Если я сделаю

 MyXMLDoc.CreateNode(XmlNodeType.DocumentFragment, "SOAP-ENV", "Envelope", "http://tempuri.org");
  

Это не позволяет мне добавлять атрибуты. В нем говорится, что они доступны только для чтения.

ВОЗОБНОВЛЕНИЕ:

Что я должен сделать, чтобы написать это, но без root и с объявлением XmlDeclaration? и как мне вызвать веб-сервис (с этим xml)?

 -<root>
  <SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" /> 
- <SOAP-ENV:Body>
- <ZbcInsertRequest xmlns:ns1="'urn:sap-com:document:sap:soap:functions:mc-style'">
  <Destino>qas</Destino> 
- <IClrQst>
  <Request>foo</Request> 
  <Proyecto>foofoo</Proyecto> 
  <Modulocq /> 
  <Titureq>foofoofoo</Titureq> 
  <Tiporeq /> 
  <Prioridad>0</Prioridad> 
  <Clasific /> 
  <Asignadoa>foofoofoofoo</Asignadoa> 
  <Destino>qas</Destino> 
  <Solicita>foo</Solicita> 
  <Autoriza>c.foo</Autoriza> 
  <ModTransp /> 
  <ReqSox>F</ReqSox> 
  <Notfylst /> 
  <Tipodeploy>Normal</Tipodeploy> 
  <Paqdeploy>CDVQA00000000</Paqdeploy> 
  </IClrQst>
- <TRequest>
- <item>
  <Trkorr>DESK9A0ZJT</Trkorr> 
  <Secuencia>0</Secuencia> 
  <Solicita>c.foo</Solicita> 
  <Type /> 
  <Id /> 
  <Numero /> 
  <Message /> 
  </item>
  </TRequest>
  </ZbcInsertRequest>
  </SOAP-ENV:Body>
  </root>
  

Вот wsdl, к которому я подключаюсь

 <wsdl:definitions targetNamespace="urn:sap-com:document:sap:soap:functions:mc-style">
<wsdl:types>
<xsd:schema targetNamespace="urn:sap-com:document:sap:rfc:functions" elementFormDefault="unqualified" attributeFormDefault="qualified">
<xsd:simpleType name="char1">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char10">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char100">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="100"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char15">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="15"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char20">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="20"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char220">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="220"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char255">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char30">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char32">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="32"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char50">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numeric3">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="3"/>
<xsd:pattern value="d*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numeric6">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="6"/>
<xsd:pattern value="d*"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
<xsd:schema targetNamespace="urn:sap-com:document:sap:soap:functions:mc-style" elementFormDefault="unqualified" attributeFormDefault="qualified">
<xsd:import namespace="urn:sap-com:document:sap:rfc:functions"/>
<xsd:simpleType name="char1">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char10">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char12">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="12"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char120">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="120"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char20">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="20"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char250">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="250"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char3">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="3"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char4">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="4"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="char60">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="60"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="date">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
<xsd:pattern value="dddd-dd-dd"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numeric5">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="5"/>
<xsd:pattern value="d*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numeric6">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="6"/>
<xsd:pattern value="d*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="time">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="8"/>
<xsd:pattern value="dd:dd:dd"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="ZtyEE070">
<xsd:sequence>
<xsd:element name="Trkorr" type="tns:char20"/>
<xsd:element name="As4text" type="tns:char60"/>
<xsd:element name="Trfunction" type="n0:char1"/>
<xsd:element name="Trstatus" type="n0:char1"/>
<xsd:element name="Tarsystem" type="tns:char10"/>
<xsd:element name="Korrdev" type="tns:char4"/>
<xsd:element name="As4user" type="tns:char12"/>
<xsd:element name="As4date" type="tns:date"/>
<xsd:element name="As4time" type="tns:time"/>
<xsd:element name="Strkorr" type="tns:char20"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ZtyEE071">
<xsd:sequence>
<xsd:element name="Trkorr" type="n0:char20"/>
<xsd:element name="As4pos" type="tns:numeric6"/>
<xsd:element name="Pgmid" type="tns:char4"/>
<xsd:element name="Object" type="tns:char4"/>
<xsd:element name="Objname" type="tns:char120"/>
<xsd:element name="Objfunc" type="tns:char1"/>
<xsd:element name="Lockflag" type="tns:char1"/>
<xsd:element name="Gennum" type="tns:char3"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Zclrqstdat">
<xsd:sequence>
<xsd:element name="Request" type="n0:char15"/>
<xsd:element name="Proyecto" type="n0:char50"/>
<xsd:element name="Modulocq" type="tns:char250"/>
<xsd:element name="Titureq" type="tns:char250"/>
<xsd:element name="Tiporeq" type="n0:char30"/>
<xsd:element name="Prioridad" type="n0:char15"/>
<xsd:element name="Clasific" type="n0:char100"/>
<xsd:element name="Asignadoa" type="n0:char50"/>
<xsd:element name="Destino" type="n0:char10"/>
<xsd:element name="Solicita" type="n0:char50"/>
<xsd:element name="Autoriza" type="n0:char50"/>
<xsd:element name="Modtransp" type="n0:char1"/>
<xsd:element name="Reqsox" type="n0:char1"/>
<xsd:element name="Notfylst" type="n0:char255"/>
<xsd:element name="Tipodeploy" type="n0:char50"/>
<xsd:element name="Paqdeploy" type="n0:char15"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Zrequest">
<xsd:sequence>
<xsd:element name="Trkorr" type="n0:char20"/>
<xsd:element name="Secuencia" type="tns:numeric5"/>
<xsd:element name="Solicita" type="n0:char50"/>
<xsd:element name="Type" type="n0:char1"/>
<xsd:element name="Id" type="n0:char20"/>
<xsd:element name="Numero" type="n0:numeric3"/>
<xsd:element name="Message" type="n0:char220"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Bapiret2">
<xsd:sequence>
<xsd:element name="Type" type="n0:char1"/>
<xsd:element name="Id" type="n0:char20"/>
<xsd:element name="Number" type="n0:numeric3"/>
<xsd:element name="Message" type="n0:char220"/>
<xsd:element name="Logno" type="n0:char20"/>
<xsd:element name="Logmsgno" type="n0:numeric6"/>
<xsd:element name="Messagev1" type="n0:char50"/>
<xsd:element name="Messagev2" type="n0:char50"/>
<xsd:element name="Messagev3" type="n0:char50"/>
<xsd:element name="Messagev4" type="n0:char50"/>
<xsd:element name="Parameter" type="n0:char32"/>
<xsd:element name="Row" type="xsd:int"/>
<xsd:element name="Field" type="n0:char30"/>
<xsd:element name="System" type="n0:char10"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TableOfztyEE070">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded" type="tns:ZtyEE070"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TableOfztyEE071">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded" type="tns:ZtyEE071"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TableOfzrequest">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded" type="tns:Zrequest"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="ZbcInsertRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Destino" type="n0:char32"/>
<xsd:element name="EtRequestHeader" minOccurs="0" type="tns:TableOfztyEE070"/>
<xsd:element name="EtRequestObj" minOccurs="0" type="tns:TableOfztyEE071"/>
<xsd:element name="IClrqst" type="tns:Zclrqstdat"/>
<xsd:element name="TRequest" type="tns:TableOfzrequest"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ZbcInsertRequestResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EtRequestHeader" minOccurs="0" type="tns:TableOfztyEE070"/>
<xsd:element name="EtRequestObj" minOccurs="0" type="tns:TableOfztyEE071"/>
<xsd:element name="Return" type="tns:Bapiret2"/>
<xsd:element name="TRequest" type="tns:TableOfzrequest"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ZbcInsertRequestString">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EtRequestHeader" minOccurs="0" type="tns:TableOfztyEE070"/>
<xsd:element name="EtRequestObj" minOccurs="0" type="tns:TableOfztyEE071"/>
<xsd:element name="Sdestino" type="xsd:string"/>
<xsd:element name="SiClrqst" type="xsd:string"/>
<xsd:element name="TRequest" type="tns:TableOfzrequest"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ZbcInsertRequestStringResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EtRequestHeader" type="tns:TableOfztyEE070"/>
<xsd:element name="EtRequestObj" type="tns:TableOfztyEE071"/>
<xsd:element name="Return" type="tns:Bapiret2"/>
<xsd:element name="TRequest" type="tns:TableOfzrequest"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<style/>
<wsdl:message name="ZbcInsertRequest">
<wsdl:part name="parameters" element="tns:ZbcInsertRequest"/>
</wsdl:message>
<wsdl:message name="ZbcInsertRequestResponse">
<wsdl:part name="parameters" element="tns:ZbcInsertRequestResponse"/>
</wsdl:message>
<wsdl:message name="ZbcInsertRequestString">
<wsdl:part name="parameters" element="tns:ZbcInsertRequestString"/>
</wsdl:message>
<wsdl:message name="ZbcInsertRequestStringResponse">
<wsdl:part name="parameters" element="tns:ZbcInsertRequestStringResponse"/>
</wsdl:message>
<sap:Feature name="design_0 " uri="http://www.sap.com/webas/630/soap/features/authentication/">
<sap:Property qname="n1:AuthenticationLevel">
<sap:Option value="n1:None"/>
</sap:Property>
</sap:Feature>
<wsdl:portType name="ZICQ">
<sap:useFeature feature="tns:design_0 "/>
<wsdl:operation name="ZbcInsertRequest">
<wsdl:input message="tns:ZbcInsertRequest"/>
<wsdl:output message="tns:ZbcInsertRequestResponse"/>
</wsdl:operation>
<wsdl:operation name="ZbcInsertRequestString">
<wsdl:input message="tns:ZbcInsertRequestString"/>
<wsdl:output message="tns:ZbcInsertRequestStringResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ZICQSoapBinding" type="tns:ZICQ">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ZbcInsertRequest">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ZbcInsertRequestString">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ZICQService">
<wsdl:port name="ZICQSoapBinding" binding="tns:ZICQSoapBinding">
<soap:address location="http://hmxwasd1.hylsamex.com.mx:8000/sap/bc/srt/rfc/sap/ZICQ?sap-client=100"/>
</wsdl:port>
  

Ответ №1:

Что касается вашего конкретного вопроса: в конверте SOAP элемент Body должен быть дочерним элементом конверта. Нельзя, чтобы конверт был пустым элементом, а тело следовало за ним. Приведенный ниже код показывает, как загрузить измененную версию этого документа в объект XmlDocument.

     public class StackOverflow_6157636_751090
    {
        public static void Test()
        {
            string xml = @"  <SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xs=""http://www.w3.org/2001/XMLSchema""> 
 <SOAP-ENV:Body>
 <ZbcInsertRequest xmlns:ns1=""urn:sap-com:document:sap:soap:functions:mc-style"">
  <Destino>qas</Destino> 
 <IClrQst>
  <Request>foo</Request> 
  <Proyecto>foofoo</Proyecto> 
  <Modulocq /> 
  <Titureq>foofoofoo</Titureq> 
  <Tiporeq /> 
  <Prioridad>0</Prioridad> 
  <Clasific /> 
  <Asignadoa>foofoofoofoo</Asignadoa> 
  <Destino>qas</Destino> 
  <Solicita>foo</Solicita> 
  <Autoriza>c.foo</Autoriza> 
  <ModTransp /> 
  <ReqSox>F</ReqSox> 
  <Notfylst /> 
  <Tipodeploy>Normal</Tipodeploy> 
  <Paqdeploy>CDVQA00000000</Paqdeploy> 
  </IClrQst>
 <TRequest>
 <item>
  <Trkorr>DESK9A0ZJT</Trkorr> 
  <Secuencia>0</Secuencia> 
  <Solicita>c.foo</Solicita> 
  <Type /> 
  <Id /> 
  <Numero /> 
  <Message /> 
  </item>
  </TRequest>
  </ZbcInsertRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            MemoryStream ms = new MemoryStream();
            Encoding encoding = new UTF8Encoding(false);
            XmlWriter w = XmlWriter.Create(ms, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = false, Encoding = encoding, IndentChars = "  " });
            doc.Save(w);
            w.Flush();
            Console.WriteLine(encoding.GetString(ms.ToArray()));
        }
    }
  

Теперь другой вариант, который вы можете рассмотреть (если это возможно), заключается не в отправке запроса SOAP «вручную», а в использовании какого-либо инструмента (такого как WCF или какая-либо другая библиотека SOAP) для создания прокси, который вы можете использовать для отправки запросов в службу. Таким образом, ваш клиент может просто «вызвать метод», и стек позаботится о создании конверта SOAP для вас.

Комментарии:

1. Спасибо за ваш ответ. Дело в том, что я пытался, но файл reference.cs не компилируется, и даже когда я меняю ссылки для компиляции, возвращаемый результат выдает ошибку десериализации (типичная ошибка sap, не проясняющая, из websvc, который я вызываю). Кроме того, нет ли способа сделать это, обрабатывая структуру xml с помощью xmlnode и / или xmlelement? потому что я не уверен, что создание большой строки является лучшим, поскольку я должен объединить значения каждого xml-тега. И еще одно: где и как вы обрабатываете ответ, который это выдает?

2. Если ссылка не компилируется, значит, это ошибка в ссылке Добавить веб / сервис — если вы можете опубликовать WSDL, который использовался для ее создания, я могу передать команде WCF.

3. @carlosfigueira, На самом деле WSDL работает так, как вы опубликовали вначале… И это действительно работает. Но это ужасно для рефакторинга или исправления.

4. Я имею в виду, что так было раньше . (Я не создаю новое подключение к веб-сервису), я только рефакторингую его. Это было сделано в vbscript с asp3.0, но сейчас мы работаем с . net и это пришлось перенести на текущую технологию. Я не могу изменить веб-метод, потому что здесь задействованы некоторые привилегии и бюрократия. Есть идеи?

5. Я считаю это правильным ответом, потому что это так, но моя проблема остается.