Per both the SOAP 1.1 spec and the WS-I BP, faults must be described
as document/literal -- even if the input and output messages are
rpc/encoded. Perhaps that's why .NET is having so much trouble.

Anne


On Tue, 15 Mar 2005 20:11:45 -0800, Dino Chiesa <[EMAIL PROTECTED]> wrote:
>  
> > Does .NET uses XMLSerializer behind the scenes to perform
> serialization/deserialization of SOAP messages? 
>   
> Yes, it can, but not SOAP Section-5 encoded messages.  In .NET, that is done
> by the SOAP serializer. 
>   
> > Is there an alternative preferred/standard mechanism to define array types
> in the WSDL? 
>   
> Yes, see 
> http://wiki.apache.org/ws/DotNetInteropArrays?action=show 
>   
> > Assuming I was not using the funky array stuff, and just trying to
> deserialize a standard object with xsd string/int attributes etc by using
> the detail element inside a SoapException, do you know how you would go
> about doing this? 
>   
> Like this?   
>   
>       catch (System.Web.Services.Protocols.SoapException ex1) {
>         Console.WriteLine("SOAP Exception: '{0}'", ex1.ToString());
>         if (ex1.Detail != null) { 
>   
>           System.Xml.Serialization.XmlSerializer ser= new
> System.Xml.Serialization.XmlSerializer(typeof(FdkException)); 
>   
>           System.IO.StringReader sr= new
> System.IO.StringReader(ex1.Detail.InnerXml);
>           FdkException fault= (FdkException) ser.Deserialize(new
> System.Xml.XmlTextReader(sr)); 
>   
>           Console.WriteLine("fault.errorCode: '{0}'", fault.errorCode);
>           Console.WriteLine("fault.stack: '{0}'", fault.serverStackTraceId);
>           // etc 
>         }
>         else
>           Console.WriteLine("detail is null!");
>       }
>  
> 
> The FdkException has to be exposed into the WSDL, so that it gets generated
> into the client-side proxy class.  or it must otherwise be known to the
> client.  
>  
>  
>  ________________________________
>  From: M S [mailto:[EMAIL PROTECTED] 
> Sent: Tuesday, March 15, 2005 9:23 PM
> To: axis-user@ws.apache.org
> Subject: RE: Using .NET how to deserialize obj from detail element of SOAP
> fault sentby AXIS?
> 
>  
>  
>  
>  
> 
> Hi Dino, 
> 
> Thanks for your reply. 
> 
> Does .NET uses XMLSerializer behind the scenes to perform
> serialization/deserialization of SOAP messages? 
> 
> If so, it seems to support these complex array types (defined in the same
> .WSDL file) fine - and I didn't do anything tricky to make this happen
> either.  I just used the web reference tool to point to the WSDL file and
> woila! 
> 
> 
> For example, on a successful login, the server returns a loginResponse
> message that is defined as following: 
> 
> <wsdl:message name="loginResponse">
>   <wsdl:part name="loginReturn" type="impl:ArrayOfNamedValue" /> 
> </wsdl:message> 
> 
> <complexType name="NamedValue">
>   <sequence>
>     <element name="name" nillable="true" type="xsd:string" /> 
>     <element name="value" nillable="true" type="xsd:anyType" /> 
>   </sequence>
> </complexType> 
> 
> <complexType name="ArrayOfNamedValue">
>   <complexContent>
>     <restriction base="soapenc:Array">
> <attribute ref="soapenc:arrayType" wsdl:arrayType="impl:NamedValue[]" /> 
>     </restriction>
>   </complexContent>
> </complexType> 
> 
> <complexType name="Item">
>   <sequence>
>     <element name="id" type="xsd:long" /> 
>     <element name="name" nillable="true" type="xsd:string" /> 
>     <element name="requestedAttributes" nillable="true"
> type="impl:ArrayOfNamedValue" /> 
>     <element name="type" nillable="true" type="xsd:string" /> 
>   </sequence>
> </complexType> 
> 
> 
> Where: xmlns:impl="http://xmlns.mycompany.com/app/ws"; 
> and: xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";
> and: xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
> 
> 
> In my code, the following works perfectly: 
> 
> int sessionTimeout = -1, transactionTimeout = -1;
> Item user = null;
> NamedValue[] nvArray = null;
> try
> {
>   nvArray = rlManager.login(username,password);
> }
> catch(System.Web.Services.Protocols.SoapException e)
> {
>   throw;
> }
> for (int i=0; i <nvArray.Length; i++)
> {
>   switch (nvArray[i].name)
>   {
>     case WebServiceConstants.LOGIN_USER:
>       if (!(nvArray[i].value is Item))
>         throw new
> exception.UnexpectedTypeException(WebServiceConstants.LOGIN_USER + " not an
> Item.");
>       user = (Item) nvArray[i].value;
>       if (user.type != ItemTypes.USER)
>         throw new
> exception.UnexpectedTypeException(WebServiceConstants.LOGIN_USER + " not an
> Item of type " + ItemTypes.USER);
>       break;
>     case WebServiceConstants.SESSION_TIMEOUT:
>       if (!(nvArray[i].value is Int32))
>         throw new
> exception.UnexpectedTypeException(WebServiceConstants.SESSION_TIMEOUT + "
> not an Int32.");
>       sessionTimeout = (Int32) nvArray[i].value;
>       break;
>     case WebServiceConstants.TRANSACTION_TIMEOUT:
>       if (!(nvArray[i].value is Int32))
>         throw new
> exception.UnexpectedTypeException(WebServiceConstants.TRANSACTION_TIMEOUT +
> " not an Int32.");
>       transactionTimeout = (Int32) nvArray[i].value;
>       break;
>     default:
>       break;
>   }
> }
> if (user == null)
> {
>   throw new exception.AccessDeniedException();
> } 
> 
> Is there an alternative preferred/standard mechanism to define array types
> in the WSDL? 
> 
> Assuming I was not using the funky array stuff, and just trying to
> deserialize a standard object with xsd string/int attributes etc by using
> the detail element inside a SoapException, do you know how you would go
> about doing this? 
> 
> many thanks, 
> 
> Matt.
>  
> 
> 
> 
>   
> >From: "Dino Chiesa" <[EMAIL PROTECTED]> 
> >Reply-To: axis-user@ws.apache.org 
> >To: <axis-user@ws.apache.org> 
> >Subject: RE: Using .NET how to deserialize obj from detail element of SOAP
> fault sentby AXIS? 
> >Date: Tue, 15 Mar 2005 17:32:05 -0800 
> > 
> >first, 
> >get rid of that 
> >soapenc:Array 
> >stuff. 
> > 
> >.NET's XML Serializer won't handle that ! 
> > 
> >The SOAP serializer might, but .... 
> >I can't help you there. 
> > 
> > 
> > 
> > 
> > 
> >________________________________ 
> > 
> >From: M S [mailto:[EMAIL PROTECTED] 
> >Sent: Tuesday, March 15, 2005 6:53 PM 
> >To: axis-user@ws.apache.org 
> >Subject: Using .NET how to deserialize obj from detail element of SOAP 
> >fault sentby AXIS? 
> > 
> > 
> > 
> >Hello, 
> > 
> >I'm trying to build a C# client to consume an AXIS Web Service (running 
> >SOAP over HTTP).  The Web Service encodes full server-side exception 
> >traces in the Soap Fault > Detail element using complex type structures 
> >declared in the WSDL file. 
> > 
> > 
> > 
> >I have had absolutely no luck working out how I can deserialize the 
> >custom server exception object out of the detail element using .NET 
> >(C#).  I' wondering if anyone in the AXIS community has done this 
> >before? 
> > 
> > 
> > 
> >I have tried both SoapFormatter, and XmlSerializer with absolutely no 
> >luck. 
> > 
> > 
> > 
> >try 
> > 
> >{ 
> > 
> >     <<<< e.g. login operation >>>> 
> > 
> >} 
> > 
> >catch (System.Web.Services.Protocols.SoapException e) 
> > 
> >{ 
> > 
> >   XmlReader reader = null; 
> > 
> >   XmlWriter writer = null; 
> > 
> >   MemoryStream mem = new MemoryStream(); 
> > 
> >   FdkException fe = null; 
> > 
> > 
> > 
> >   try 
> > 
> >   { 
> > 
> >     reader = new XmlNodeReader(e.Detail.FirstChild); 
> > 
> >     writer = new XmlTextWriter(mem, System.Text.Encoding.UTF8); 
> > 
> >     writer.WriteNode(reader,true); 
> > 
> >     writer.Flush(); 
> > 
> >     mem.Position = 0; 
> > 
> > 
> > 
> >     <<<< Add deserialization code here >>>> 
> > 
> >     fe = (FdkException) .... 
> > 
> >   } 
> > 
> >   catch (Exception ex) 
> > 
> >   { 
> > 
> >     System.Console.WriteLine(ex.toString()); 
> > 
> >     throw; 
> > 
> >   } 
> > 
> >} 
> > 
> > 
> > 
> >The first deserialization mechansim I tried was using 
> >System.Runtime.Serialization.Formatters.Soap.SoapFormatter 
> > 
> > 
> > 
> >SoapFormatter sf = new SoapFormatter(); 
> > 
> >sf.Binder = new FdkExceptionDeserializationBinder(); 
> > 
> >fe = (FdkException) sf.Deserialize(mem); 
> > 
> > 
> > 
> >With FdkExceptionDeserializationBinder.cs looking like the following: 
> > 
> > 
> > 
> >public class FdkExceptionDeserializationBinder : 
> >System.Runtime.Serialization.SerializationBinder 
> > 
> >{ 
> > 
> >   public override Type BindToType(string assemblyName, string typeName) 
> > 
> >   { 
> > 
> >     if (assemblyName.Equals("http://xmlns.mycompany.com/app/ws";)) 
> > 
> >     { 
> > 
> >       switch (typeName) 
> > 
> >       { 
> > 
> >         case "FdkException" : return typeof(FdkException); break; 
> > 
> >         case "ArrayOfFdkExceptionEntry" : return 
> >typeof(FdkExceptionEntry[]); break; 
> > 
> >       } 
> > 
> >     } 
> > 
> >     return Type.GetType(String.Format("{0}, {1}", typeName, 
> >assemblyName)); 
> > 
> >   } 
> > 
> >} 
> > 
> > 
> > 
> >This deserialization approach resulted in an exception: 
> > 
> >Exception Type: System.Runtime.Serialization.SerializationException 
> > 
> >Message: No Top Object 
> > 
> >Source: System.Runtime.Serialization.Formatters.Soap 
> > 
> > 
> > 
> > 
> > 
> >The second deserialization mechanism I tried was using XmlSerializer: 
> > 
> >XmlTypeMapping myMapping = (new 
> >SoapReflectionImporter().ImportTypeMapping(typeof(FdkException))); 
> > 
> >XmlSerializer serializer = new XmlSerializer(myMapping); 
> > 
> >fe = (FdkException) serializer.Deserialize(mem); 
> > 
> > 
> > 
> >I set Soap options in the FdkException class: 
> > 
> > 
> > 
> >using System; 
> > 
> >using System.Xml.Serialization; 
> > 
> >... 
> > 
> >[Serializable] 
> > 
> >[SoapTypeAttribute(Namespace="http://xmlns.mycompany.com/app/ws";, 
> >TypeName="fault")] 
> > 
> >public class FdkException 
> > 
> >{ 
> > 
> >   public string errorCode; 
> > 
> >   public FdkExceptionEntry[] exceptionEntries; 
> > 
> >   public string serverStackTraceId; 
> > 
> >} 
> > 
> > 
> > 
> >using System; 
> > 
> >using System.Xml.Serialization; 
> > 
> >[Serializable] 
> > 
> >[SoapTypeAttribute(Namespace="http://xmlns.mycompany.com/app/ws";, 
> >TypeName="FdkExceptionEntry")] 
> > 
> >public class FdkExceptionEntry 
> > 
> >{ 
> > 
> >   public string errorCode; 
> > 
> >   public long id; 
> > 
> >   public string serverStackTraceId; 
> > 
> >} 
> > 
> > 
> > 
> > 
> > 
> >I got the following exception: 
> > 
> >Message: There is an error in XML Document (1,541). 
> > 
> >Exception Type: System.InvalidOperationException 
> > 
> >Source: System.Xml 
> > 
> > 
> > 
> >Inner Exception: 
> > 
> >Message: Cannot assign object of type System.Xml.XmlNode[] to an object 
> >of type FdkException 
> > 
> >Exception Type: System.InvalidCastException 
> > 
> > 
> > 
> > 
> > 
> >Below is the SOAP message returned from the server on an invalid logon 
> >attempt (including Fault):- 
> > 
> > 
> > 
> > 
> > 
> ><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:Body> 
> > 
> >     <soapenv:Fault> 
> > 
> >       <faultcode>soapenv:Server.userException</faultcode> 
> > 
> >       <faultstring>AccessDenied</faultstring> 
> > 
> >       <detail> 
> > 
> >         <ns1:fault xsi:type="ns1:FdkException" 
> >xmlns:ns1="http://xmlns.mycompany.com/app/ws";> 
> > 
> >           <errorCode xsi:type="soapenc:string" 
> >xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";>AccessDenied - 
> >Invalid Credentials</errorCode> 
> > 
> >           <exceptionEntries xsi:type="ns1:ArrayOfFdkExceptionEntry" 
> >xsi:nil="true"/> 
> > 
> >           <serverStackTraceId xsi:type="soapenc:string" 
> >xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"/> 
> > 
> >         </ns1:fault> 
> > 
> >       </detail> 
> > 
> >     </soapenv:Fault> 
> > 
> >   </soapenv:Body> 
> > 
> ></soapenv:Envelope> 
> > 
> > 
> > 
> > 
> > 
> >Below is relevant pieces of the WSDL file relating to the FdkException 
> >object: 
> > 
> > 
> > 
> ><wsdl:types> 
> > 
> >   <schema xmlns="http://www.w3.org/2001/XMLSchema"; 
> >targetNamespace="http://xmlns.mycompany.com/app/ws";> 
> > 
> >     <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> 
> > 
> >     <complexType name="FdkExceptionEntry"> 
> > 
> >       <sequence> 
> > 
> >         <element name="errorCode" nillable="true" type="xsd:string"/> 
> > 
> >         <element name="id" type="xsd:long"/> 
> > 
> >         <element name="serverStackTraceId" nillable="true" 
> >type="xsd:string"/> 
> > 
> >       </sequence> 
> > 
> >     </complexType> 
> > 
> >     <complexType name="ArrayOfFdkExceptionEntry"> 
> > 
> >       <complexContent> 
> > 
> >         <restriction base="soapenc:Array"> 
> > 
> >           <attribute ref="soapenc:arrayType" 
> >wsdl:arrayType="impl:FdkExceptionEntry[]"/> 
> > 
> >         </restriction> 
> > 
> >       </complexContent> 
> > 
> >     </complexType> 
> > 
> >     <complexType name="FdkException"> 
> > 
> >       <sequence> 
> > 
> >         <element name="errorCode" nillable="true" type="xsd:string"/> 
> > 
> >         <element name="exceptionEntries" nillable="true" 
> >type="impl:ArrayOfFdkExceptionEntry"/> 
> > 
> >         <element name="serverStackTraceId" nillable="true" 
> >type="xsd:string"/> 
> > 
> >       </sequence> 
> > 
> >     </complexType> 
> > 
> >   </schema> 
> > 
> ></wsdl:types> 
> > 
> > 
> > 
> ><wsdl:message name="FdkException"> 
> > 
> >   <wsdl:part name="fault" type="impl:FdkException"/> 
> > 
> ></wsdl:message> 
> > 
> > 
> > 
> ><wsdl:portType name="RemoteLoginManager"> 
> > 
> >   <wsdl:operation name="login" parameterOrder="username password"> 
> > 
> >     <wsdl:input name="loginRequest" message="impl:loginRequest"/> 
> > 
> >     <wsdl:output name="loginResponse" message="impl:loginResponse"/> 
> > 
> >     <wsdl:fault name="FdkException" message="impl:FdkException"/> 
> > 
> >   </wsdl:operation> 
> > 
> ></wsdl:portType> 
> > 
> > 
> > 
> ><wsdl:binding name="RemoteLoginManagerSoapBinding" 
> >type="impl:RemoteLoginManager"> 
> > 
> >   <wsdlsoap:binding style="rpc" 
> >transport="http://schemas.xmlsoap.org/soap/http"/> 
> > 
> >   <wsdl:operation name="login"> 
> > 
> >     <wsdlsoap:operation/> 
> > 
> >     <wsdl:input> 
> > 
> >       <wsdlsoap:body use="encoded" 
> >encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; 
> >namespace="http://xmlns.mycompany.com/app/ws"/> 
> > 
> >     </wsdl:input> 
> > 
> >     <wsdl:output> 
> > 
> >       <wsdlsoap:body use="encoded" 
> >encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; 
> >namespace="http://xmlns.mycompany.com/app/ws"/> 
> > 
> >     </wsdl:output> 
> > 
> >     <wsdl:fault name="FdkException"> 
> > 
> >       <wsdlsoap:fault name="FdkException" use="encoded" 
> >encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; 
> >namespace="http://xmlns.mycompany.com/app/ws"/> 
> > 
> >     </wsdl:fault> 
> > 
> >   </wsdl:operation> 
> > 
> ></wsdl:binding> 
> > 
> > 
> > 
> > 
> > 
> >Has anyone out there been able to deserialize from SOAP fault detail 
> >element using C#? 
> > 
> > 
> > 
> >many thanks, 
> > 
> > 
> > 
> >Matt. 
> > 
> > 
> >________________________________ 
> > 
> >Try the new Beta version of MSN Messenger - it's FREE! 
> ><http://g.msn.com/8HMBENUS/2752??PS=47575> 
> 
>  ________________________________
>  Try the new Beta version of MSN Messenger - it's FREE!

Reply via email to