RE: [SOAP] Re: Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error
| From: | Dmitry Stogov | Date: | Wed, 18 Jan 2006 08:07:53 +0000 |
| Subject: | RE: [SOAP] Re: Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error | ||
| References: | 1 | Groups: | php.soap |
| Request: | Send a blank email to php-soap+get-2079@lists.php.net to get a copy of this message | ||
H Peter,
This is well known issue, but not a php/soap bug.
The problem that some SOAP implementations don't confirm to SOAP
specification and don't accept types derived from array.
See: http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383522
"SOAP arrays are defined as having a type of "SOAP-ENC:Array" or A TYPE
DERIVED THERE FROM."
Thanks. Dmitry.
> -----Original Message-----
> From: Peter Guy [mailto:pguy@vrcis.com]
> Sent: Wednesday, January 18, 2006 3:52 AM
> To: soap@lists.php.net
> Subject: [SOAP] Re: Java/Oracle server, PHP 5.1.2 client,
> array of complexTypes, Deserializer error
>
>
> Since this is such a long post, I'll put all of my comments
> up here, rather than throughout the post or at the bottom.
>
> Thanks for taking the time to generate more stubs, and
> confirming my suspicions that this is a PHP bug, Michael.
>
> However, you state that, "The error is that php names the
> individual structs/complex types item...", but I'm pretty
> sure the error is in the xsi:type attribute of the BARS
> element. PHP fills the xsi:type attribute with "<my
> namespace>:ArrayOfBar", when it should be "<SOAP-ENC
> namespace>:Array".
> Every other client I've seen specifies the type of an array
> element as "<SOAP-ENC namespace>:Array", so I'm almost sure
> that this is a PHP bug.
>
> Where do I go from here? Shall I submit a PHP bug report?
>
> -Peter
>
> "Michael Rasmussen" <mir@miras.org> wrote in message
> news:pan.2006.01.18.00.19.56.504455@miras.org...
> > On Tue, 17 Jan 2006 11:04:21 -0800, Peter Guy wrote:
> >
> > > So, my questions:
> > >
> > > 1. Is the WSDL formatted the right way for PHP? Could it be
> > > formatted differently, so as to coerce PHP into supplying the
> > > correct "type" for
> the
> > > BARS element?
> > Well, it seems to be correct wsdl. mono(C#) and
> gsoap(c/c++) has now
> > problems in creating a correct proxy: The mono proxy:
> >
> //
> --------------------------------------------------------------
> -----------
> -----
> > // <autogenerated>
> > // This code was generated by a tool.
> > // Mono Runtime Version: 1.1.4322.2032
> > //
> > // Changes to this file may cause incorrect behavior
> and will be lost
> if
> > // the code is regenerated.
> > // </autogenerated>
> >
> //
> --------------------------------------------------------------
> -----------
> -----
> >
> > //
> > // This source code was auto-generated by Mono Web Services
> > Description
> Language Utility
> > //
> >
> > /// <remarks/>
> > [System.Web.Services.WebServiceBinding(Name="CustomerServicePort",
> Namespace="http://CustomerService.wsdl")]
> > [System.Diagnostics.DebuggerStepThroughAttribute()]
> > [System.ComponentModel.DesignerCategoryAttribute("code")]
> > [System.Xml.Serialization.SoapInclude(typeof(Bar))]
> > public class CustomerService :
> System.Web.Services.Protocols.SoapHttpClientProtocol {
> >
> > public CustomerService() {
> > this.Url =
> "http://vrcweb1.vrcis.com/custserv/CustomerService";
> > }
> >
> > [System.Web.Services.Protocols.SoapRpcMethodAttribute("",
> RequestNamespace="CustomerService",
> ResponseNamespace="CustomerService")]
> > [return: System.Xml.Serialization.SoapElement("return")]
> > public Bar[] EchoBars(Bar[] BARS) {
> > object[] results = this.Invoke("EchoBars", new object[] {
> > BARS});
> > return ((Bar[])(results[0]));
> > }
> >
> > public System.IAsyncResult BeginEchoBars(Bar[] BARS,
> System.AsyncCallback callback, object asyncState) {
> > return this.BeginInvoke("EchoBars", new object[] {
> > BARS}, callback, asyncState);
> > }
> >
> > public Bar[] EndEchoBars(System.IAsyncResult asyncResult) {
> > object[] results = this.EndInvoke(asyncResult);
> > return ((Bar[])(results[0]));
> > }
> > }
> >
> > /// <remarks/>
> >
>
> [System.Xml.Serialization.SoapType(Namespace="http://www.vrcis
> .com/CustomerS
> erviceAPIV1")]
> > public class Bar {
> >
> > /// <remarks/>
> > public string NAME;
> > }
> >
> > The gsoap proxy:
> > /** @mainpage CustomerService Definitions
> >
> > @section CustomerServiceBinding Service Binding
> > "CustomerServiceBinding"
> >
> > @subsection CustomerServiceBinding_operations Operations
> >
> > - @ref ns1__EchoBars
> >
> > @subsection CustomerServiceBinding_ports Endpoint Ports
> >
> > - http://vrcweb1.vrcis.com/custserv/CustomerService
> >
> > */
> >
> > // Note: modify this file to customize the generated data type
> declarations
> >
> > //gsoapopt w
> > #import "stl.h"
> > /// Built-in attribute "SOAP-ENC:arrayType"
> > typedef char *SOAP_ENC__arrayType;
> >
> > /*
> > To customize the names of the namespace prefixes generated
> by wsdl2h,
> modify
> > the prefix names below and add the modified lines to typemap.dat to
> > run
> wsdl2h:
> >
> > ns2 = http://www.vrcis.com/CustomerServiceAPIV1
> > */
> >
> > //gsoap ns2 schema namespace:
> http://www.vrcis.com/CustomerServiceAPIV1
> > //gsoap ns2 schema form: unqualified
> >
> > // Forward declarations
> > class ArrayOfBar;
> > class ns2__Bar;
> >
> > // End of forward declarations
> >
> >
> > /// Schema http://www.vrcis.com/CustomerServiceAPIV1
> complexType "Bar"
> >
> > class ns2__Bar
> > { public:
> > /// Element NAME of type xs:string
> > std::string NAME
> ;
> ///< Required element
> > /// A handle to the soap struct context that manages this
> class instance
> > struct soap *soap
> ;
> > };
> >
> > /// Schema http://www.vrcis.com/CustomerServiceAPIV1
> > complexType
> "ArrayOfBar"
> >
> > /// SOAP encoded array of
> > "http://www.vrcis.com/CustomerServiceAPIV1":Bar
> > class ArrayOfBar
> > { public:
> > /// Pointer to an array of ns2__Bar*
> > ns2__Bar* *__ptr
> ;
> > /// Size of the dynamic array
> > int __size
> ;
> > /// A handle to the soap struct context that manages this
> class instance
> > struct soap *soap
> ;
> > };
> >
> > //gsoap ns1 service name: CustomerServiceBinding
> > //gsoap ns1 service type: CustomerServicePortType
> > //gsoap ns1 service port:
> http://vrcweb1.vrcis.com/custserv/CustomerService
> > //gsoap ns1 service namespace: CustomerService
> >
> > /// Operation response struct "ns1__EchoBarsResponse" of service
> > binding
> "CustomerServiceBinding" operation "ns1__EchoBars"
> > struct ns1__EchoBarsResponse
> > {
> > ArrayOfBar* return_;
> > };
> >
> > /// Operation "ns1__EchoBars" of service binding
> > "CustomerServiceBinding"
> >
> > /**
> >
> > Operation details:
> >
> > - SOAP RPC
>
> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
> >
> > C stub function (defined in soapClient.c[pp]):
> > @code
> > int soap_call_ns1__EchoBars(struct soap *soap,
> > NULL, // char *endpoint = NULL selects default endpoint for this
> operation
> > NULL, // char *action = NULL selects default action for
> this operation
> > ArrayOfBar* BARS,
> > struct ns1__EchoBarsResponse&
> > );
> > @endcode
> >
> > C++ proxy class (defined in soapCustomerServiceBindingProxy.h):
> > class CustomerServiceBinding;
> >
> > */
> >
> > //gsoap ns1 service method-style: EchoBars rpc
> > //gsoap ns1 service method-encoding: EchoBars
> http://schemas.xmlsoap.org/soap/encoding/
> > //gsoap ns1 service method-action: EchoBars ""
> > int ns1__EchoBars(
> > ArrayOfBar* BARS,
> > struct ns1__EchoBarsResponse& );
> >
> > /* End of CustomerService Definitions */
> >
> > Parsing output from php:
> > Supported functions:
> > ArrayOfBar EchoBars(ArrayOfBar $BARS)
> > Supported types:
> > Bar ArrayOfBar[]
> > struct Bar {
> > string NAME;
> > }
> > Produced with this code:
> > $client = new SoapClient(
> >
> > 'http://vrcweb1.vrcis.com/custserv/CustomerService?WSDL',
> > $options
> > );
> > if ($functions = $client->__getFunctions())
> > {
> > echo "Supported functions:\n";
> > foreach ($functions as $function)
> > echo $function, "\n";
> > }
> > if ($types = $client->__getTypes())
> > {
> > echo "Supported types:\n";
> > foreach ($types as $type)
> > echo $type, "\n";
> > }
> >
> > The reason that it is not working in php is a bug in the proxy that
> > php is creating!
> >
> > The request sent:
> > <BARS SOAP-ENC:arrayType="ns2:Bar[1]" xsi:type="ns2:ArrayOfBar">
> >
> > <item xsi:type="ns2:Bar">
> > <NAME xsi:type="xsd:string">bar none</NAME>
> > </item>
> > </BARS>
> >
> > This is how it should be - which your http-client
> demonstrates: <BARS
> > SOAP-ENC:arrayType="ns1:Bar[1]" xsi:type="SOAP-ENC:Array">
> > <Bar xsi:type="ns1:Bar">
> > <NAME xsi:type="xsd:string">String Value</NAME>
> > </Bar>
> > </BARS>
> >
> > The error is that php names the individual structs/complex
> types item
> > but they must be named Bar. The error is therefore on the
> client side
> > (php) which does not send a correct formated request. I am
> possitively
> > convinced that receiving will work as can be seen under supported
> > types above. You could try sending a raw xml request to your server
> > but let php handle the response to have this observation confirmed.
> >
> > --
> > Hilsen/Regards
> > Michael Rasmussen
> >
>
> http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917
>
> --
> PHP Soap Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
>