Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

c# - Delphi SOAP Envelope and WCF

I am working on a system that provides a soap interface. One of the systems that are going to use the interface is coded in Delphi 7. The web service is developed with WCF, basic http binding, SOAP 1.1.

If I use SOAP UI (JAVA), the service works properly. But Delphi seems to do special things here ;)

This is how the message looks like in SOAP UI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.xxx.de/xxx">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:GetCustomer>
         <!--Optional:-->
         <ser:GetCustomerRequest> <!-- this is a data contract -->
            <ser:Id>?</ser:Id>
         </ser:GetCustomerRequest>
      </ser:GetCustomer>
   </soapenv:Body>
</soapenv:Envelope>

I am not a delphi developer , but I developed a simple test client to see what's going wrong. This what Delphi sends as a SOAP envelope.

<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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="http://services.xxx.de/xxx">
    <NS1:GetCustomer xmlns:NS1="http://services.xxx.de/xxx">
      <GetCustomerRequest href="#1"/>
    </NS1:GetCustomer>
    <NS2:GetCustomerRequest id="1" xsi:type="NS2:GetCustomerRequest">
      <Id xsi:type="xsd:int">253</Id>
    </NS2:GetCustomerRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

WCF throws an error that is in German language... ;)

Es wurde das Endelement "Body" aus Namespace "http://schemas.xmlsoap.org/soap/envelope/" erwartet. Gefunden wurde "Element "NS2:GetCustomerRequest" aus Namespace "http://services.xxx.de/xxx"". Zeile 1, Position 599.

Means something like

The Body was expected. But instead the Element "NS2:GetCustomerReques" was found.

Now my questions is: Can I somehow change the way Delphi creates the envelope? Or are the ways to make WCF work with such message formats? Any help is greatly appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Contrary to what some people here seem to be implying, Delphi is not sending invalid SOAP, it is simply sending RPC/Encoded SOAP. It's very easy to recognize from all the xsi:type attributes. RPC/Encoded is not WS-I compliant but it is still valid SOAP.

WCF, by default, uses the Document/Literal/Wrapped SOAP format, which Delphi 7 can't handle at all on the server side and you have to make some adjustments on the client side.

The simplest solution is to simply tell Delphi to use the Document/Literal style. You do that by turning on soLiteralParams in the THttpRio.Converter.Options. This tells Delphi not to "unwind" the parameters as you are seeing. The "Document" aspect is something that the Delphi WSDL importer can usually figure out so you shouldn't need to worry about that.

The other solution is to tell the WCF service to use RPC/Encoded style, which you can do by adding the following attributes to the service:

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

The second is not recommended because, as I mentioned earlier, RPC/Encoded is not WS-I compliant, but nevertheless most SOAP toolkits do recognize it, so I list it here as a possibility.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...