.NET Forum / ASP.NET / Web Services / June 2004
.net client + Axis 1.1 server + wrapped param: null result
|
|
Thread rating:  |
Zihong Lu - 18 Jun 2004 03:30 GMT I have used the following settings in our web services:
.net framework 1.1 web services client Axis 1.1 server (in wsdd file, set style="wrapped")
Using axis client calls the server, it works fine. However, .net client always returns null, even though the soap message has the result, for example, for the simple function
string getSession(string username, string password);
The SOAP messages in the response seems to be normal, as shown in this request/response message:
====== Request ====== <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <getSession xmlns="urn:myname.com"> <username xmlns="">admin</username> <password xmlns="" /> </getSession> </soap:Body> </soap:Envelope>
====== Response ====== 287 <?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:sessionID soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0" xmlns:ns1="http://xml.apache.org/axis/session"> 7413200230928429396 </ns1:sessionID> </soapenv:Header> <soapenv:Body> <getSessionResponse xmlns="urn:myname.com"> <getSessionReturn>7413200230928429396</getSessionReturn> </getSessionResponse> </soapenv:Body> </soapenv:Envelope> 0
No, I don't know why there is a 287 before <?xml> tag and a 0 at the end of the response message. This may have something to do with the response HTTP header
Transfer-Encoding: chunked
in responding to the .net request HTTP header of "Connection: Keep-Alive".
The session ID in SOAP header doesn't seem matter, since I tested the call with and without the session ID header. I have serached this group for almost a day, the closest I have found is this link:
http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
However, it was talking about serializing complex type there. Can someone plese help?
-Zihong
Dino Chiesa [Microsoft] - 18 Jun 2004 21:01 GMT you showed the request and response - I guess that would be a request from .NET to AXIS and a response from AXIS to .NET. Can I see the WSDL? or failing that, the client-side proxy generated by wsdl.exe ??
I am betting it is an xml namespace issue.
-D
> I have used the following settings in our web services: > [quoted text clipped - 56 lines] > call with and without the session ID header. I have serached this > group for almost a day, the closest I have found is this link: http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
> However, it was talking about serializing complex type there. Can > someone plese help? > > -Zihong Zihong Lu - 18 Jun 2004 22:54 GMT Dino,
Thank you for looking into this. Yes the request/response messages are .net->axis (request) and axis->.net(response).
Here is the WSDL that I use (Note that I commented out the <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> for getSession(), because it is another issue that causing .net confused, it does not know what "xsd:long" is.) ================================== <?xml version="1.0" encoding="UTF-8" ?> <wsdl:definitions targetNamespace="urn:myname.com" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:myname.com" xmlns:intf="urn:myname.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:session="http://xml.apache.org/axis/session">
<documentation />
<wsdl:types>
<schema targetNamespace="http://xml.apache.org/axis/session" xmlns="http://www.w3.org/2001/XMLSchema"> <simpleType name="session"> <restriction base="xsd:long"/> </simpleType> <element name="sessionID" type="session:session"/> </schema>
<schema targetNamespace="urn:myname.com" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="getSession"> <complexType> <sequence> <element name="username" type="xsd:string" /> <element name="password" type="xsd:string" /> </sequence> </complexType> </element>
<element name="getSessionResponse"> <complexType> <sequence> <element name="getSessionReturn" type="xsd:string" /> </sequence> </complexType> </element>
<element name="closeSession"> <complexType /> </element>
<element name="closeSessionResponse"> <complexType /> </element>
</schema> </wsdl:types>
<wsdl:message name="soapHeader"> <wsdl:part name="sessionID" element="session:sessionID" /> </wsdl:message>
<wsdl:message name="getSessionRequest"> <wsdl:part element="impl:getSession" name="parameters" /> </wsdl:message>
<wsdl:message name="getSessionResponse"> <wsdl:part element="impl:getSessionResponse" name="parameters" /> </wsdl:message>
<wsdl:message name="closeSessionRequest"> <wsdl:part element="impl:closeSession" name="parameters" /> </wsdl:message>
<wsdl:message name="closeSessionResponse"> <wsdl:part element="impl:closeSessionResponse" name="parameters" /> </wsdl:message>
<wsdl:portType name="MynameService">
<wsdl:operation name="getSession" parameterOrder=""> <wsdl:input message="impl:getSessionRequest" name="getSessionRequest" /> <wsdl:output message="impl:getSessionResponse" name="getSessionResponse" /> </wsdl:operation>
<wsdl:operation name="closeSession"> <wsdl:input message="impl:closeSessionRequest" name="closeSessionRequest" /> <wsdl:output message="impl:closeSessionResponse" name="closeSessionResponse" /> </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MynameServiceSoapBinding" type="impl:MynameService"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getSession"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="getSessionRequest"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:input> <wsdl:output name="getSessionResponse"> <!-- comment it out. There is another bug in .net for this --> <!-- wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/ --> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:output> </wsdl:operation>
<wsdl:operation name="closeSession"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="closeSessionRequest"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:input> <wsdl:output name="closeSessionResponse"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:output> </wsdl:operation>
</wsdl:binding>
<wsdl:service name="MynameServiceService"> <wsdl:port binding="impl:MynameServiceSoapBinding" name="MynameService"> <wsdlsoap:address location="http://localhost:8080/services/MynameService" /> </wsdl:port> </wsdl:service>
</wsdl:definitions>
============================================
Generated cs file: ============================================ namespace MyNameSpace{ using System.Diagnostics; using System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.ComponentModel; using System.Web.Services;
/// <remarks/> [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi ng", Namespace="urn:myname.com")] public class MynameServiceService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public session sessionID;
/// <remarks/> public MynameServiceService() { this.Url = "http://localhost:8080/services/MynameService"; }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] [return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] string password) { object[] results = this.Invoke("getSession", new object[] { username, password}); return ((string)(results[0])); }
/// <remarks/> public System.IAsyncResult BegingetSession(string username, string password, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("getSession", new object[] { username, password}, callback, asyncState); }
/// <remarks/> public string EndgetSession(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public void closeSession() { this.Invoke("closeSession", new object[0]); }
/// <remarks/> public System.IAsyncResult BegincloseSession(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("closeSession", new object[0], callback, asyncState); }
/// <remarks/> public void EndcloseSession(System.IAsyncResult asyncResult) { this.EndInvoke(asyncResult); } }
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/ axis/session")] [System.Xml.Serialization.XmlRootAttribute("sessionID", Namespace="http://xml.apache.org/axis/session", IsNullable=false)] public class session : System.Web.Services.Protocols.SoapHeader {
/// <remarks/> [System.Xml.Serialization.XmlTextAttribute()] public string[] Text; } }
==================================================
> you showed the request and response - I guess that would be a request from > .NET to AXIS and a response from AXIS to .NET. [quoted text clipped - 67 lines] > > call with and without the session ID header. I have serached this > > group for almost a day, the closest I have found is this link: http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
> > However, it was talking about serializing complex type there. Can > > someone plese help? > > > > -Zihong Dino Chiesa [Microsoft] - 19 Jun 2004 06:28 GMT Yes, A namespace problem . To fix this change the attribute on the getSession() method in the generated client side proxy to Qualified, from Unqualified
[return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn", Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
Or, you can modify the WSDL to accurately reflect what AXIS is sending back:
<element name="getSessionReturn" type="xsd:string" form="qualified" />
and then regenerate the client proxy.
AXIS is a bit loose with its elementforms (qualified vs unqualified). The WSDL doesn't specify it, yet the behavior for the request and response is different. -D
> Dino, > [quoted text clipped - 159 lines] > [System.Diagnostics.DebuggerStepThroughAttribute()] > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> ng", Namespace="urn:myname.com")] > public class MynameServiceService : [quoted text clipped - 17 lines] > Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] string password) { > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 42 lines] > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> axis/session")] > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 80 lines] > > > call with and without the session ID header. I have serached this > > > group for almost a day, the closest I have found is this link: http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
> > > However, it was talking about serializing complex type there. Can > > > someone plese help? > > > > > > -Zihong Zihong Lu - 20 Jun 2004 01:21 GMT Dino,
Thanks. That works.
Now I have a second issue: the soap header. As you can see from my eariler wsdl file, if I do the following: (1) changed the line to <element name="getSessionReturn" type="xsd:string" form="qualified"/>, to solve the null result problem; (2) uncommented out the line to indicate the soap header in the return message: <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal" />
When invoke the getSession() call, the .net client complained:
========================================= System.InvalidOperationException: The specified type was not recognized: name='long', namespace='http://www.w3.org/2001/XMLSchema', at <sessionID xmlns='http://xml.apache.org/axis/session'>.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_ session(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_ OutHeaders()
Do I need to create serializer/deserializer for the SOAP header? I thought the created proxy code already recognize it and can serialize it automatically, like gSoap does.
Here is the new generated client proxy: ============================ namespace MyNameSpace{ using System.Diagnostics; using System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.ComponentModel; using System.Web.Services;
/// <remarks/> [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi ng", Namespace="urn:myname.com")] public class MynameServiceService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public session sessionID;
/// <remarks/> public MynameServiceService() { this.Url = "http://localhost:8080/services/MynameService"; }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] [return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] string password) { object[] results = this.Invoke("getSession", new object[] { username, password}); return ((string)(results[0])); }
/// <remarks/> public System.IAsyncResult BegingetSession(string username, string password, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("getSession", new object[] { username, password}, callback, asyncState); }
/// <remarks/> public string EndgetSession(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public void closeSession() { this.Invoke("closeSession", new object[0]); }
/// <remarks/> public System.IAsyncResult BegincloseSession(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("closeSession", new object[0], callback, asyncState); }
/// <remarks/> public void EndcloseSession(System.IAsyncResult asyncResult) { this.EndInvoke(asyncResult); } }
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/ axis/session")] [System.Xml.Serialization.XmlRootAttribute("sessionID", Namespace="http://xml.apache.org/axis/session", IsNullable=false)] public class session : System.Web.Services.Protocols.SoapHeader {
/// <remarks/> [System.Xml.Serialization.XmlTextAttribute()] public string[] Text; } }
> Yes, A namespace problem . > To fix this [quoted text clipped - 182 lines] > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > ng", Namespace="urn:myname.com")] > > public class MynameServiceService : [quoted text clipped - 12 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > [return: > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn", > > Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] string password) { > > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 23 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > public void closeSession() { > > this.Invoke("closeSession", new object[0]); > > } > > > > /// <remarks/> > > public System.IAsyncResult BegincloseSession(System.AsyncCallback
> > callback, object asyncState) { > > return this.BeginInvoke("closeSession", new object[0], [quoted text clipped - 9 lines] > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > axis/session")] > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 81 lines] > > > > call with and without the session ID header. I have serached this > > > > group for almost a day, the closest I have found is this link: http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
> > > > However, it was talking about serializing complex type there. Can > > > > someone plese help? > > > > > > > > -Zihong Dino Chiesa [Microsoft] - 21 Jun 2004 16:02 GMT If I modify your WSDL to type the session ID this way:
<element name="sessionID" type="sess:session"/>
<complexType name="session"> <sequence> <element minOccurs="1" maxOccurs="1" name="s" type="xsd:long"/> </sequence> </complexType>
it works, and generates a header class like so:
public class session : System.Web.Services.Protocols.SoapHeader { /// <remarks/> [System.Xml.Serialization.XmlElementAttribute()] public long s; }
I think the problem is, in .NET the soapheader must derive from System.Web.Services.Protocols.SoapHeader . In other words it is a complexType. In your WSDL you have it as a simpleType. Generating a client proxy from that WSDL results in some confusion. Feels like a bug in the wsdl.exe compiler.
The simple fix is to change the definition of the header type in XSD to the above. This generates what you would expect, I think.
But you have to ensure this synchronizes with the AXIS server. If you are generating the server from the WSDL then it should be no problem .
-Dino
> Dino, > [quoted text clipped - 18 lines] > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> session(Boolean isNullable, Boolean checkType) > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> OutHeaders() > [quoted text clipped - 15 lines] > [System.Diagnostics.DebuggerStepThroughAttribute()] > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> ng", Namespace="urn:myname.com")] > public class MynameServiceService : [quoted text clipped - 17 lines] > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] string password) { > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 42 lines] > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> axis/session")] > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 196 lines] > > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > > ng", Namespace="urn:myname.com")] > > > public class MynameServiceService : [quoted text clipped - 8 lines] > > > > > > /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID")]
> > > [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", > > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", [quoted text clipped - 5 lines] > > > Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] > > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > maForm.Unqualified)] string password) { > > > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 19 lines] > > > > > > /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID",
> > > Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] > > > [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", [quoted text clipped - 22 lines] > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > axis/session")] > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 85 lines] > > > > > call with and without the session ID header. I have serached this > > > > > group for almost a day, the closest I have found is this link: http://groups.google.com/groups?selm=71b15e3e.0403031046.7ad66ce6%40posting.goog le.com
> > > > > However, it was talking about serializing complex type there. Can > > > > > someone plese help? > > > > > > > > > > -Zihong Zihong Lu - 21 Jun 2004 19:52 GMT Dino,
I have changed the session declaration in WSDL to what you suggested, as showing here:
<schema targetNamespace="http://xml.apache.org/axis/session" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="sessionID" type="sens:session"/> <complexType name="session"> <sequence> <element minOccurs="1" maxOccurs="1" name="id" type="xsd:long"/> </sequence> </complexType> </schema>
where namespace "sens" was defined in the <wsdl:definitions> as xmlns:sens="http://xml.apache.org/axis/session".
Yes, the generated proxy code now has the same session class derived from SoapHeader, as earlier. However, compared to the code generated from simpleType declaration in WSDL earlier , the class memeber "id" now has a data type of long, instead of the earlier string[], and it has a sensible name "id" that I set, instead of the earlier generated name of "Text" (these are the only changes in the whole generated client proxy file):
/// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/ axis/session")] [System.Xml.Serialization.XmlRootAttribute("sessionID", Namespace="http://xml.apache.org/axis/session", IsNullable=false)] public class session : System.Web.Services.Protocols.SoapHeader {
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] public long id; }
I have noticed that the "id" is unqulified, while in the example you showed the "s" does not have the "Unqualified" attribute.
However, even with this change, I still got the same error of InvalidOperationException. Since the wsdl file is manually edited, I did not change Axis server side. For the session handling, I simply use SimpleSessionHandler handler, a convenient handler that Axis provided.
I have also tested the code with the "Form = ... Unqualified" manually removed from the generated proxy code, I still got the same error. The eror message is copied here again for completeness: ======================================= Unhandled Exception: System.InvalidOperationException: There is an error in XML document (4, 4). ---> System.InvalidOperationException: The specified type was n ot recognized: name='long', namespace='http://www.w3.org/2001/XMLSchema', at <se ssionID xmlns='http://xml.apache.org/axis/session'>. at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read 1_session(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read 8_OutHeaders() =======================================
The returned SOAP message is <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:sessionID soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1="http://xml.apache.org/axis/session">-5227012230670020468</ns1:ses sionID> </soapenv:Header> ...
the position (4,4) indicated in the error message is the ns1:sessionID tag. Does this message looks right to you, compared to what WSDL declared? Somehow I felt the xsi:type="xsd:long" is not right, since dot/lit style don't usually have this.
-Zihong
> If I modify your WSDL to type the session ID this way: > [quoted text clipped - 52 lines] > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> > session(Boolean isNullable, Boolean checkType) > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> > OutHeaders() > > [quoted text clipped - 16 lines] > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > ng", Namespace="urn:myname.com")] > > public class MynameServiceService : [quoted text clipped - 13 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > [return: > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] string password) { > > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 23 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > public void closeSession() { > > this.Invoke("closeSession", new object[0]); > > } > > > > /// <remarks/> > > public System.IAsyncResult BegincloseSession(System.AsyncCallback
> > callback, object asyncState) { > > return this.BeginInvoke("closeSession", new object[0], [quoted text clipped - 9 lines] > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > axis/session")] > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 6 lines] > > } > > } Dino Chiesa [Microsoft] - 21 Jun 2004 22:37 GMT yes, I think you are correct. the xsi:type="xsd:long" seems to be incorrect.
BUT!
We are changing the WSDL here without modifying the server. The WSDL documents how we would like the service to appear, but if we design the WSDL independently of the implementation of the service (in AXIS) , then there is no way of knowing if the two independent things coincide.
It appears that AXIS is using doc/literal for the SOAP body and soap-section-5 encoded for the SOAP header. Can you check this in the server/service implementation?
--------------------
It seems like you may be using the AXIS SimpleSessionHandler ? If so, there are others who have tried to get this to work and had troubles, for example see the axis user mailing list archive, eg http://marc.theaimsgroup.com/?l=axis-user&m=107694009529949&w=2
or http://marc.theaimsgroup.com/?l=axis-user&m=104204463001241&w=2
or to search the archive: http://marc.theaimsgroup.com/?l=axis-user&w=2&r=1&s=sessionhandler&q=b
The problem is that AXIS's WSDL2Java tool does not handle soapheaders as defined in WSDL. If you have a WSDL (such as you have constructed here) that specifies a soapheader to be used in the input message, the output message, or both, then the Java implementation generated from AXIS' "wsdl2java --server-side" does not have any support for that header. As a developer using AXIS, you need to provide a handler to extract the header, or insert the header, as appropriate.
The "SimpleSessionHandler" code included with AXIS v1.1 shows this. As you can see, there is some DOM walking you have to do to extract the header and de-marshal it and validate it and so on. I suppose there is similar work you have to do to "add" the header to the response.
But even with all this I am not sure why the header would be section-5 encoded when the body is not. In the WSDL model, the soap body can in fact be a different "use" than the header. In other words the literal or section-5 encoded is specified on the body independently from the header. Eg,
<wsdl:output name="getSessionResponse"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:output>
-Dino
> Dino, > [quoted text clipped - 22 lines] > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> axis/session")] > [System.Xml.Serialization.XmlRootAttribute("sessionID", > Namespace="http://xml.apache.org/axis/session", IsNullable=false)] > public class session : System.Web.Services.Protocols.SoapHeader { > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] > public long id; [quoted text clipped - 34 lines] > <soapenv:Header> > <ns1:sessionID soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1="http://xml.apache.org/axis/session">-5227012230670020468</ns1:ses
> sionID> > </soapenv:Header> [quoted text clipped - 67 lines] > > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> > > session(Boolean isNullable, Boolean checkType) > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> > > OutHeaders() > > > [quoted text clipped - 16 lines] > > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > > ng", Namespace="urn:myname.com")] > > > public class MynameServiceService : [quoted text clipped - 8 lines] > > > > > > /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID",
> > > Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] > > > [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", [quoted text clipped - 5 lines] > > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > maForm.Unqualified)] string password) { > > > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 19 lines] > > > > > > /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID",
> > > Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] > > > [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", [quoted text clipped - 22 lines] > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > axis/session")] > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 6 lines] > > > } > > > } Zihong Lu - 22 Jun 2004 02:36 GMT Dino,
Yes I did search the axis-users group for days before I came to asking for help in this group. For some reason the solution they provide there don't work for me.
You are right that from axis server side, I need to hand craft the skeleton codes/settings before I can use the session handler, and I did manage to overcome the problem on that side.
Back to the issue here. I have been experimenting further, by modifying the wsdl file namespace. Then, magically, the getSession() function call succeeded. From that point view, the xsi:type may not be an issue.
But, problems are not finished yet, the subsequent call closeSession() from the .bet client does not have the sessionID included in the header. This is the .net->axis request for closeSession() after the getSession() call:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <closeSession xmlns="urn:myname.com" /> </soap:Body> </soap:Envelope>
Any idea?
Here is the modified WSDL: ======================================== <?xml version="1.0" encoding="UTF-8" ?> <wsdl:definitions targetNamespace="urn:myname.com" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:myname.com" xmlns:intf="urn:myname.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sens="http://xml.apache.org/axis/session">
<wsdl:types>
<schema targetNamespace="urn:myname.com" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="sessionID" type="impl:session" /> <complexType name="session"> <sequence> <element minOccurs="1" maxOccurs="1" name="id" type="xsd:long" /> </sequence> </complexType>
<element name="getSession"> <complexType> <sequence> <element name="username" type="xsd:string" /> <element name="password" type="xsd:string" /> </sequence> </complexType> </element>
<element name="getSessionResponse"> <complexType> <sequence> <element name="getSessionReturn" type="xsd:string" form="qualified" /> </sequence> </complexType> </element>
<element name="closeSession"> <complexType /> </element>
<element name="closeSessionResponse"> <complexType /> </element>
</schema> </wsdl:types>
<wsdl:message name="soapHeader"> <wsdl:part name="sessionID" element="impl:sessionID" /> </wsdl:message>
<wsdl:message name="getSessionRequest"> <wsdl:part element="impl:getSession" name="parameters" /> </wsdl:message>
<wsdl:message name="getSessionResponse"> <wsdl:part element="impl:getSessionResponse" name="parameters" /> </wsdl:message>
<wsdl:message name="closeSessionRequest"> <wsdl:part element="impl:closeSession" name="parameters" /> </wsdl:message>
<wsdl:message name="closeSessionResponse"> <wsdl:part element="impl:closeSessionResponse" name="parameters" /> </wsdl:message>
<wsdl:portType name="MynameService">
<wsdl:operation name="getSession" parameterOrder=""> <wsdl:input message="impl:getSessionRequest" name="getSessionRequest" /> <wsdl:output message="impl:getSessionResponse" name="getSessionResponse" /> </wsdl:operation>
<wsdl:operation name="closeSession"> <wsdl:input message="impl:closeSessionRequest" name="closeSessionRequest" /> <wsdl:output message="impl:closeSessionResponse" name="closeSessionResponse" /> </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MynameServiceSoapBinding" type="impl:MynameService"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getSession"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="getSessionRequest"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:input> <wsdl:output name="getSessionResponse"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:output> </wsdl:operation>
<wsdl:operation name="closeSession"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="closeSessionRequest"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:input> <wsdl:output name="closeSessionResponse"> <wsdlsoap:header message="impl:soapHeader" part="sessionID" use="literal"/> <wsdlsoap:body namespace="urn:myname.com" use="literal" /> </wsdl:output> </wsdl:operation>
</wsdl:binding>
<wsdl:service name="MynameServiceService"> <wsdl:port binding="impl:MynameServiceSoapBinding" name="MynameService"> <wsdlsoap:address location="http://localhost:8080/services/MynameService" /> </wsdl:port> </wsdl:service>
</wsdl:definitions> ====================================
This is the created client proxy:
namespace MyNameSpace{
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi ng", Namespace="urn:myname.com")]
public class MynameServiceService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public session sessionID;
/// <remarks/>
public MynameServiceService() {
this.Url = "http://localhost:8080/services/MynameService";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn")]
public string getSession([System.Xml.Serialization.XmlElementdttribute(Form=System.Xml.Sch ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] string password) {
object[] results = this.Invoke("getSession", new object[] {
username,
password});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BegingetSession(string username, string password, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("getSession", new object[] {
username,
password}, callback, asyncState);
}
/// <remarks/>
public string EndgetSession(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((string)(results[0]));
}
/// <remarks/>
[System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void closeSession() {
this.Invoke("closeSession", new object[0]);
}
/// <remarks/>
public System.IAsyncResult BegincloseSession(System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("closeSession", new object[0], callback, asyncState);
}
/// <remarks/>
public void EndcloseSession(System.IAsyncResult asyncResult) {
this.EndInvoke(asyncResult);
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:myname.com")]
[System.Xml.Serialization.XmlRootAttribute("sessionID", Namespace="urn:myname.com", IsNullable=false)]
public class session : System.Web.Services.Protocols.SoapHeader {
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)]
public long id;
}
}
> yes, I think you are correct. the xsi:type="xsd:long" seems to be > incorrect. [quoted text clipped - 78 lines] > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > axis/session")] > > [System.Xml.Serialization.XmlRootAttribute("sessionID", > > Namespace="http://xml.apache.org/axis/session", IsNullable=false)] > > public class session : System.Web.Services.Protocols.SoapHeader { > > > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] > > public long id; [quoted text clipped - 24 lines] > > ssionID xmlns='http://xml.apache.org/axis/session'>. > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read
> > 1_session(Boolean isNullable, Boolean checkType) > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read
> > 8_OutHeaders() > > ======================================= [quoted text clipped - 7 lines] > > <soapenv:Header> > > <ns1:sessionID soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1="http://xml.apache.org/axis/session">-5227012230670020468</ns1:ses
> > sionID> > > </soapenv:Header> [quoted text clipped - 70 lines] > > > > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> > > > session(Boolean isNullable, Boolean checkType) > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> > > > OutHeaders() > > > > [quoted text clipped - 16 lines] > > > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > > > ng", Namespace="urn:myname.com")] > > > > public class MynameServiceService : [quoted text clipped - 11 lines] > [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", > > > > Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("",
> > > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > > > [return: > > > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > > > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > > maForm.Unqualified)] string password) { > > > > object[] results = this.Invoke("getSession", new object[] [quoted text clipped - 23 lines] > [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", > > > > Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("",
> > > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > > > public void closeSession() { > > > > this.Invoke("closeSession", new object[0]); [quoted text clipped - 16 lines] > > > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > > axis/session")] > > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 6 lines] > > > > } > > > > } Zihong Lu - 22 Jun 2004 03:29 GMT I believe my approach is wrong. Because the element type "sessionID" is defined in the "impl" namespace, ie, the urn:myname.com namespace, which means that upon return in getSession() call, the .net client will look for the sessionID in the urn:myname.com namespace. However, in the return message, axis sends the header in the http://xml.apache.org/axis/session namespace, as shown here for axis->.net response to getSession():
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"> <soapenv:Header> <ns2:sessionID soapenv:mustUnderstand="0" xsi:type="ns1:long" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="http://www.w3.org/2001/XMLSchema"
xmlns:ns2="http://xml.apache.org/axis/session">-3876663609367995448</ns2:ses sionID> </soapenv:Header> <soapenv:Body> <getSessionResponse xmlns="urn:myname.com"> <getSessionReturn>-3876663609367995448</getSessionReturn> </getSessionResponse> </soapenv:Body> </soapenv:Envelope>
since .net did not find anything in the urn:myname.com namespace, it simply ignore the header, hence the getSession() call returned nicely, no error. However, it did not get the session ID in the header either, hence, no session ID in the subsequent closeSession() call.
Well, back to the same problem.
-Zihong
> Dino, > [quoted text clipped - 183 lines] > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> ng", Namespace="urn:myname.com")] > [quoted text clipped - 24 lines] > > public string getSession([System.Xml.Serialization.XmlElementdttribute(Form=System.Xml.Sch
> ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] string password) { > [quoted text clipped - 77 lines] > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] > [quoted text clipped - 95 lines] > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > axis/session")] > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", > > > Namespace="http://xml.apache.org/axis/session", IsNullable=false)] > > > public class session : System.Web.Services.Protocols.SoapHeader { > > > > > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > maForm.Unqualified)] > > > public long id; [quoted text clipped - 44 lines] > > > <soapenv:Header> > > > <ns1:sessionID soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1="http://xml.apache.org/axis/session">-5227012230670020468</ns1:ses
> > > sionID> > > > </soapenv:Header> [quoted text clipped - 73 lines] > > > > > > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> > > > > session(Boolean isNullable, Boolean checkType) > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> > > > > OutHeaders() > > > > > [quoted text clipped - 16 lines] > > > > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > > > > ng", Namespace="urn:myname.com")] > > > > > public class MynameServiceService : [quoted text clipped - 11 lines] > > > > > > > [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
> [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", > > > > > RequestNamespace="urn:myname.com", [quoted text clipped - 5 lines] > > > > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > > > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > > > > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > > > maForm.Unqualified)] string password) { > > > > > object[] results = this.Invoke("getSession", new [quoted text clipped - 24 lines] > > > > > > > [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
> [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", > > > > > RequestNamespace="urn:myname.com", [quoted text clipped - 23 lines] > > > > > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > > > axis/session")] > > > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 7 lines] > > > > > } > > > > > } Dino Chiesa [Microsoft] - 22 Jun 2004 06:49 GMT why do you not define your session type (in the WSDL) to be in the proper namespace?
eg
<schema targetNamespace="http://xml.apache.org/axis/session" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" > <element name="sessionID" type="sess:session"/>
<complexType name="session"> <sequence> <element minOccurs="1" maxOccurs="1" name="id" type="xsd:long"/> </sequence> </complexType>
</schema>
Does this not work?
> I believe my approach is wrong. Because the element type "sessionID" is > defined in the "impl" namespace, ie, the urn:myname.com namespace, which [quoted text clipped - 11 lines] > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xmlns:ns1="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/axis/session">-3876663609367995448</ns2:ses
> sionID> > </soapenv:Header> [quoted text clipped - 206 lines] > > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > ng", Namespace="urn:myname.com")] > > [quoted text clipped - 19 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > [return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > > > public string getSession([System.Xml.Serialization.XmlElementdttribute(Form=System.Xml.Sch
> > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] string password) { > > [quoted text clipped - 40 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > public void closeSession() { > > [quoted text clipped - 33 lines] > > > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] > > [quoted text clipped - 101 lines] > > > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > > axis/session")] > > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", > > > > Namespace="http://xml.apache.org/axis/session", IsNullable=false)] > > > > public class session : System.Web.Services.Protocols.SoapHeader { > > > > > > > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > > maForm.Unqualified)] > > > > public long id; [quoted text clipped - 30 lines] > > > > ssionID xmlns='http://xml.apache.org/axis/session'>. > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read
> > > > 1_session(Boolean isNullable, Boolean checkType) > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read
> > > > 8_OutHeaders() > > > > ======================================= [quoted text clipped - 7 lines] > > > > <soapenv:Header> > > > > <ns1:sessionID soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1="http://xml.apache.org/axis/session">-5227012230670020468</ns1:ses
> > > > sionID> > > > > </soapenv:Header> [quoted text clipped - 80 lines] > > > > > > > > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read1_
> > > > > > session(Boolean isNullable, Boolean checkType) > > > > > > at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_
> > > > > > OutHeaders() > > > > > > [quoted text clipped - 17 lines] > > > > > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > > > > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > > > > > ng", Namespace="urn:myname.com")] > > > > > > public class MynameServiceService : [quoted text clipped - 18 lines] > > ResponseNamespace="urn:myname.com", > > > > > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > > > > > [return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn")]
> > > > > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > > > > > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > > > > > maForm.Unqualified)] string password) { > > > > > > object[] results = this.Invoke("getSession", new [quoted text clipped - 33 lines] > > ResponseNamespace="urn:myname.com", > > > > > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > > > > > public void closeSession() { > > > > > > this.Invoke("closeSession", new object[0]); [quoted text clipped - 18 lines] > > > > > > > > > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > > > > > axis/session")] > > > > > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 8 lines] > > > > > > } > > > > > > } Zihong Lu - 22 Jun 2004 22:47 GMT I see, you have the elementFormDefault="qualified" in the schema tag. I did your way, with almost identical <schema> tag for the session ID:
<schema targetNamespace="http://xml.apache.org/axis/session" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <complexType name="session"> <sequence> <element minOccurs="1" maxOccurs="1" name="id" type="xsd:long"/> </sequence> </complexType> <element name="sessionID" type="sens:session"/> </schema>
Now, the getSession() function returns nicely!!! However, the subsequent call closeSession() does not have the sessionID in the SOAP header, just like the case where I changed the sessionID namespace to urn:myname.com. The SOAP message is the same too (see earlier message for detail).
Also, with the simpleType decalration:
<schema targetNamespace="http://xml.apache.org/axis/session" xmlns="http://www.w3.org/2001/XMLSchema"> <simpleType name="session"> <restriction base="xsd:long"/> </simpleType> <element name="sessionID" type="sens:session"/> </schema>
I could use gSoap client talking to the axis server. With the complexType declaration as we have here, the gSoap client doesn't work any more. I don't need gSoap client for now, however, it does show that different platform clients interpret it differently, and gSoap interprets it similar to Axis.
Note: if no elementFormDefault="qualified", the attribute for " public long id;" in the session class will be like this: ======================== /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] public long id; ========================
It does not help either. The generated proxy with the elementFormDefault="qualified", looks like this now: =========================== namespace MyNameSpace{ using System.Diagnostics; using System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.ComponentModel; using System.Web.Services;
/// <remarks/> [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi ng", Namespace="urn:myname.com")] public class MynameServiceService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public session sessionID;
/// <remarks/> public MynameServiceService() { this.Url = "http://localhost:8080/services/MynameService"; }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] [return: System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche maForm.Unqualified)] string password) { object[] results = this.Invoke("getSession", new object[] { username, password}); return ((string)(results[0])); }
/// <remarks/> public System.IAsyncResult BegingetSession(string username, string password, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("getSession", new object[] { username, password}, callback, asyncState); }
/// <remarks/> public string EndgetSession(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); }
/// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("sessionID", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public void closeSession() { this.Invoke("closeSession", new object[0]); }
/// <remarks/> public System.IAsyncResult BegincloseSession(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("closeSession", new object[0], callback, asyncState); }
/// <remarks/> public void EndcloseSession(System.IAsyncResult asyncResult) { this.EndInvoke(asyncResult); } }
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/ axis/session")] [System.Xml.Serialization.XmlRootAttribute("sessionID", Namespace="http://xml.apache.org/axis/session", IsNullable=false)] public class session : System.Web.Services.Protocols.SoapHeader {
/// <remarks/> public long id; } } =====================================
Dino Chiesa [Microsoft] - 23 Jun 2004 06:28 GMT I don;t know what the problem is with closeSession(). I don't think I understand where are, at this point.
You can use a simpleType in the soap header with .NET; but you don't get the automatic serialization and de-serialization. (as with AXIS, and I presume, gSOAP).
-D
> I see, you have the elementFormDefault="qualified" in the schema tag. I did > your way, with almost identical <schema> tag for the session ID: [quoted text clipped - 35 lines] > ======================== > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] > public long id; [quoted text clipped - 14 lines] > [System.Diagnostics.DebuggerStepThroughAttribute()] > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> ng", Namespace="urn:myname.com")] > public class MynameServiceService : [quoted text clipped - 17 lines] > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> maForm.Unqualified)] string password) { > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 42 lines] > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> axis/session")] > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 6 lines] > } > ===================================== Zihong Lu - 23 Jun 2004 22:53 GMT My .net client code looks like this:
long sessionId = service.getSession("admin", ""); service.closeSession();
the closeSession() is defined in the wsdl that I showed earlier, or you can see from the generated cs code.
For the complexType header, my problem with closeSession() is that after getSession(), I was hoping that the sessionID in the return SOAP header will automatically be put in the closeSession() request header, like this:
<SOAP-ENV:Header> <sessionID xmlns="http://xml.apache.org/axis/session">5419796753085587324</sessionID> </SOAP-ENV:Header>
but it did not. Actually, the closeSession() call did not include SOAP header in the request message at all. I think axis sends the rpc style headers, and the .net does wrapped style, they didn't really communicate although I did get the getSession() returned nicely. I will have to change the axis session handler SimpleSessionHandler, or customize .net header serialization/deserialization.
As for the simpleType, yes, I realized that by now. For Axis, the SimpleSessionHandler takes care of the serialization/deserialization of the header. For gSoap, it automatically recognizes the header from the wsdl, I just need to enter the namesapce correctly, ie, use the "http://xml.apache.org/axis/session" namespace, then, everything works without coding. I guess I will have to write serialization/deserialization for .net for my project, so that it will have the max interop capability.
Thanks for your help. It really helps a lot.
-Zihong
> I don;t know what the problem is with closeSession(). I don't think I > understand where are, at this point. [quoted text clipped - 47 lines] > > ======================== > > /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] > > public long id; [quoted text clipped - 14 lines] > > [System.Diagnostics.DebuggerStepThroughAttribute()] > > [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="MynameServiceSoapBindi
> > ng", Namespace="urn:myname.com")] > > public class MynameServiceService : [quoted text clipped - 13 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > [return: > > System.Xml.Serialization.XmlElementAttribute("getSessionReturn")] > > public string getSession([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Sch
> > ema.XmlSchemaForm.Unqualified)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSche
> > maForm.Unqualified)] string password) { > > object[] results = this.Invoke("getSession", new object[] { [quoted text clipped - 23 lines] > > RequestNamespace="urn:myname.com", ResponseNamespace="urn:myname.com", > > Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
> > public void closeSession() { > > this.Invoke("closeSession", new object[0]); > > } > > > > /// <remarks/> > > public System.IAsyncResult BegincloseSession(System.AsyncCallback
> > callback, object asyncState) { > > return this.BeginInvoke("closeSession", new object[0], [quoted text clipped - 9 lines] > > > > /// <remarks/> [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xml.apache.org/
> > axis/session")] > > [System.Xml.Serialization.XmlRootAttribute("sessionID", [quoted text clipped - 6 lines] > > } > > =====================================
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|