Re: Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error
| From: | Michael Rasmussen | Date: | Wed, 18 Jan 2006 00:20:01 +0000 |
| Subject: | 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-2077@lists.php.net to get a copy of this message | ||
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/CustomerServiceAPIV1")]
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