

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
17 messages in net.php.lists.soapRe: [SOAP] Re: Java/Oracle server, PH...| From | Sent On | Attachments |
|---|---|---|
| Peter Guy | Jan 17, 2006 11:03 am | |
| Peter Guy | Jan 17, 2006 12:27 pm | |
| Michael Rasmussen | Jan 17, 2006 4:19 pm | |
| Peter Guy | Jan 17, 2006 4:51 pm | |
| Dmitry Stogov | Jan 18, 2006 12:07 am | |
| Peter Guy | Jan 18, 2006 11:44 am | |
| Roger Roelofs | Jan 18, 2006 12:16 pm | |
| Michael Rasmussen | Jan 18, 2006 12:51 pm | |
| Peter Guy | Jan 18, 2006 3:18 pm | |
| Peter Guy | Jan 18, 2006 3:29 pm | |
| Dmitry Stogov | Jan 19, 2006 11:35 pm | |
| Dmitry Stogov | Jan 19, 2006 11:48 pm | |
| Dmitry Stogov | Jan 20, 2006 12:15 am | |
| Peter Guy | Jan 20, 2006 11:18 am | |
| Katy Coe | Jan 20, 2006 4:20 pm | |
| Peter Guy | Jan 20, 2006 5:26 pm | |
| Katy Coe | Jan 21, 2006 9:39 am |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [SOAP] Re: Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error | Actions... |
|---|---|---|
| From: | Katy Coe (in...@intelligentstreaming.com) | |
| Date: | Jan 20, 2006 4:20:23 pm | |
| List: | net.php.lists.soap | |
Hi everyone,
I'm using PHP 5.1.x as a client and .NET 1.1 as a server; I also am writing both the client and server end of my application. While running basic tests I noticed this problem too, just with arrays of simple types like int and string, .NET's deserialiser will complain "No type associated with Xml key <yournamespace> ArrayOfString" or some such.
As has already been discussed in the thread, I traced the problem to the xsi:type attribute generated by PHP on the element in the SOAP request that wraps all the array items. I don't know if this is a PHP bug or a .NET/Java bug as I'm not a SOAP guru, but the very simple workaround I made goes as follows:
class DotNetSoapClient extends SoapClient { public function __construct($wsdl, $options = array()) { parent::__construct($wsdl, $options); }
public function __doRequest($request, $location, $action, $version) { $dom = DOMDocument::loadXML($request); $xpath = new DOMXPath($dom);
// Array serialisation: remove the xsi:type attribute from all arrays encoded using SOAP-ENC:arrayType // as this causes an "no type associated with Xml key"-type SOAP server error in .NET $nodes = $xpath->query('/SOAP-ENV:Envelope/SOAP-ENV:Body/*//*[@SOAP-ENC:arrayType and @xsi:type]');
foreach ($nodes as $node) $node->removeAttribute('type');
$request = $dom->saveXML(); return parent::__doRequest($request, $location, $action, $version); } }
This workaround:
1. Requires no underlying knowledge of SOAP protocol to use (does not require you to form your own SOAP request) 2. Works with .NET and I assume works or is easily adapted for Java 3. Only generates one request/response roundtrip over the network 4. Can be used if you don't have access to the server
Since most web services in the real world use Java or .NET, I think that - even if this is a bug in their implementations and not PHP's - that it might be wise to at least include a flag in future versions of ext/soap that would allow the client developer to control how the request is serialised ("interop mode" or some such). From my naive perspective, that would seem to be a good compromise.
Hope the workaround helps someone anyway :-)
Katy.
At 08:18 PM 01/20/2006, Peter Guy wrote:
Dmitry,
Thank you for your attention to this thread.
I have indeed applied a workaround to the server: added a pre-filter to the servlet that finds and changes PHP's array typing to something the server understands. Check out message 2083 (http://news.php.net/php.soap/2083) for more details.
Thank you for considering a change in this area of PHP's SOAP implementation. Overall, I am impressed with PHP's SOAP implementation. From the PHP developer's point of view, it's simple, elegant, and easy to use. Just feed it a WSDL and you're off and running. This array type definition issue has been the only implementation problem with which I've had to deal.
-Peter
""Dmitry Stogov"" <dmi...@zend.com> wrote in message news:000101c61d99$b5686f80$6e02a8c0@thinkpad... Hi Peter,
Right now ext/soap hasn't workaround for this problem. I'll look and may be will create it later.
Note that some other SOAP implementations have the same interopability issue. Look into google.
http://www.google.com/search?hl=en&rls=GGLD%2CGGLD%3A2005-13%2CGGLD%3Aen&q=% 2B%22No+Deserializer+found+to+deserialize+a%22+%2Barray&lr=
May be you will find a way to fix the server itself.
Thanks. Dmitry.
-----Original Message----- From: Peter Guy [mailto:pg...@vrcis.com] Sent: Wednesday, January 18, 2006 10:45 PM To: so...@lists.php.net Subject: Re: [SOAP] Re: Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error
Thanks for the clarification, Dmitry.
I see that it is legal to type a SOAP array the way that PHP does it, but I don't think it's the right way to do it. :-)
The problem is, how will the SOAP server with which I'm dealing have any knowledge of the "type derived there from"? Unless it's written in PHP, it doesn't necessarily parse requests against the schema in the WSDL, so it likely won't have any knowledge of that derived type.
So, is there any way to cajole PHP into defining arrays with a "SOAP-ENC:Array" type rather than the "type derived there from"? Perhaps formatting the WSDL differently, like using elements rather than complex types?
Any suggestions?
-Peter
""Dmitry Stogov"" <dmi...@zend.com> wrote in message news:000001c61c06$4bfd97d0$6e02a8c0@thinkpad...
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:pg...@vrcis.com] Sent: Wednesday, January 18, 2006 3:52 AM To: so...@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 :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" <mi...@miras.org> wrote in message news:pan....@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=0xE3E809
17
-- PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
-- PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
-- PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php







