I ran in to a problem today with Flex's SOAP encoding which I think is a bug in the SOAP encoder.

It seems like whatever I did to call one of my webservice methods, Flex would give me an error as it was encoding my request. The error was something like the following: TypeError: Error #1009: Cannot access a property or method of a null object reference.
...
at mx.rpc::AbstractService/dispatchEvent()[C:\dev\enterprise_bali \frameworks\mx\rpc\AbstractService.as:236] at mx.rpc.soap.mxml::WebService/dispatchEvent()[C:\dev \enterprise_bali\frameworks\mx\rpc\soap\mxml\WebService.as:226] at mx.rpc::AbstractOperation/http://www.adobe.com/2006/flex/mx/ internal::dispatchRpcEvent()[C:\dev\enterprise_bali\frameworks\mx\rpc \AbstractOperation.as:183] at mx.rpc.soap::Operation/http://www.adobe.com/2006/flex/mx/ internal::invokePendingCall()[C:\dev\enterprise_bali\frameworks\mx\rpc \soap\Operation.as:584] at mx.rpc.soap::Operation/send()[C:\dev\enterprise_bali\frameworks\mx \rpc\soap\Operation.as:492]
        at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.rpc.soap.mxml::Operation/send()[C:\dev\enterprise_bali \frameworks\mx\rpc\soap\mxml\Operation.as:140]
        at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.rpc::AbstractService/http://www.adobe.com/2006/actionscript/ flash/proxy::callProperty()[C:\dev\enterprise_bali\frameworks\mx\rpc \AbstractService.as:287]

My program would always stop right at the encoding process. The trace stopped with these last lines:
...
19:41:19.740 [DEBUG] mx.rpc.soap.SOAPEncoder Encoding SOAP request envelope
19:41:19.745 [DEBUG] mx.rpc.soap.SOAPEncoder Encoding SOAP request body


After many attempts to try to get my very simple 1-string request encoded, I started looking in to the WSDL. Luckily I could control the WSDL - in many webservice use cases, you can not. From what I have been able to deduce, Flex's SOAP encoder will throw the above error if the name of the webservice Operation - i.e. "ListInterviews" - is not the same as the name of the message part element, i.e. "ListInterviewsRequest".

As a more thorough example, consider this WSDL, which should be fully valid (Oxygenxml and XmlSpy are both ok with it, and can generate SOAP for it):

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"; xmlns:s="http://www.w3.org/2001/XMLSchema"; xmlns:wsdl="http:// schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.yourURI.com/ OfficeService" targetNamespace="http://www.yourURI.com/OfficeService";>
        <wsdl:types>
<s:schema targetNamespace="http://www.yourURI.com/OfficeService"; elementFormDefault="qualified">
                        <s:element name="ListInterviewsRequest">
                                <s:complexType>
                                        <s:sequence>
                                                <s:element name="Token" type="s:string" 
minOccurs="1"/>
                                        </s:sequence>
                                </s:complexType>
                        </s:element>
                        <s:element name="ListInterviewsResponse">
                                <s:complexType>
                                        <s:sequence>
                                                <s:element name="InterviewList" 
type="s:string" minOccurs="0"/>
                                        </s:sequence>
                                </s:complexType>
                        </s:element>
                </s:schema>
        </wsdl:types>
        <wsdl:message name="ListInterviewsSoapIn">
                <wsdl:part name="parameters" 
element="tns:ListInterviewsRequest"/>
        </wsdl:message>
        <wsdl:message name="ListInterviewsSoapOut">
                <wsdl:part name="parameters" 
element="tns:ListInterviewsResponse"/>
        </wsdl:message>
        <wsdl:portType name="OfficeServiceSoap">
                <wsdl:operation name="ListInterviews">
                        <wsdl:input message="tns:ListInterviewsSoapIn"/>
                        <wsdl:output message="tns:ListInterviewsSoapOut"/>
                </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="OfficeServiceSoap" type="tns:OfficeServiceSoap">
                <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
                <wsdl:operation name="ListInterviews">
<soap:operation soapAction="http://www.yourURI.com/OfficeService/ ListInterviews" style="document"/>
                        <wsdl:input>
                                <soap:body use="literal"/>
                        </wsdl:input>
                        <wsdl:output>
                                <soap:body use="literal"/>
                        </wsdl:output>
                </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="OfficeService">
                <wsdl:port name="OfficeServiceSoap" 
binding="tns:OfficeServiceSoap">
<soap:address location="http://www.yourURI.com/OfficeService/ Implementation.page"/>
                </wsdl:port>
        </wsdl:service>
</wsdl:definitions>


A consumer of that webservice should be able to form a SOAP request as follows:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/ envelope/">
        <SOAP-ENV:Header/>
        <SOAP-ENV:Body>
                <ListInterviewsRequest 
xmlns="http://www.yourURI.com/OfficeService";>
                        <Token>STRING</Token>
                </ListInterviewsRequest>
        </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

So when Flex tries to generate that response, it throws the above error. As far as I can tell, it throws the error no matter how you call the webservice operation (and I called it every which way I could with Flex!).
However, when the wsdl is modified so:
<s:element name="ListInterviewsRequest"> becomes <s:element name="ListInterviews">
and
<wsdl:part name="parameters" element="tns:ListInterviewsRequest"/> becomes <wsdl:part name="parameters" element="tns:ListInterviews"/>

Flex can encode the SOAP.

Hopefully Adobe can get that fixed up, and people who are banging their head against a wall can change their WSDL (hopefully it is their own WSDL they're using) so the body element is the same as the operation name.


-graphex

Reply via email to