[Mono-devel-list] [patch] handle SOAP invocation without arguments in SoapReader

Stefan Paletta stefanp at cabal1.com
Sun Sep 12 22:36:51 EDT 2004


Hi!

Funny enough, SoapReader does not handle calls to methods that take no
arguments if serialized as an empty element (every SOAP client I
tested does that, including Mono itself).

Deserialize(Stream,ISoapMessage) reads the XML until after <soap:Body>,
then hands off to the code in DeserializeMessage(ISoapMessage) below,
and expects to be able to read the closing </soap:Body></soap:Envelope>
tags afterwards.
If the SOAP invocation was delivered as an empty element, e.g.
<soap:Body><ns1:TheMethod /></soap:Body>, the code below read until
after </soap:Body> as it expected <ns1:TheMethod></ns1:TheMethod>
rather than an empty element, and later the caller would encounter an
XmlException on its last call to xmlReader.ReadEndElement() due to
having reached EOF.

Attached is a patch to fix this issue, a diff -w is included below for
your reading convenience.

--- SoapReader.cs	24 Aug 2004 14:36:07 -0000	1.13
+++ SoapReader.cs	13 Sep 2004 01:47:18 -0000
@@ -228,9 +228,11 @@
 			long paramValuesId = NextAvailableId;
 			int[] indices = new int[1];
 
+			if (!xmlReader.IsEmptyElement)
+			{
+				int i = 0;
 			int initialDepth = xmlReader.Depth;
 			xmlReader.Read();
-			int i = 0;
 			while(xmlReader.Depth > initialDepth) 
 			{
 				long paramId, paramHref;
@@ -266,10 +268,15 @@
 				}
 				i++;
 			}
+				xmlReader.ReadEndElement();
+			}
+			else
+			{
+				xmlReader.Read();
+			}
 
 			message.ParamNames = (string[]) paramNames.ToArray(typeof(string));
 			message.ParamValues = paramValues.ToArray();
-			xmlReader.ReadEndElement();
 			RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);
 			return true;
 		}

-Stefan
-- 
 junior guru   SP666-RIPE     JID:stefanp at jabber.de.cw.net    SMP at IRC
-------------- next part --------------
Index: class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
===================================================================
RCS file: /mono/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs,v
retrieving revision 1.13
diff -u -r1.13 SoapReader.cs
--- class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	24 Aug 2004 14:36:07 -0000	1.13
+++ class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	13 Sep 2004 01:48:40 -0000
@@ -228,48 +228,55 @@
 			long paramValuesId = NextAvailableId;
 			int[] indices = new int[1];
 
-			int initialDepth = xmlReader.Depth;
-			xmlReader.Read();
-			int i = 0;
-			while(xmlReader.Depth > initialDepth) 
+			if (!xmlReader.IsEmptyElement)
 			{
-				long paramId, paramHref;
-				object objParam = null;
-				paramNames.Add (xmlReader.Name);
-				Type paramType = null;
-				
-				if (message.ParamTypes != null) {
-					if (i >= message.ParamTypes.Length)
-						throw new SerializationException ("Not enough parameter types in SoapMessages");
-					paramType = message.ParamTypes [i];
-				}
-				
-				indices[0] = i;
-				objParam = DeserializeComponent(
-					paramType,
-					out paramId,
-					out paramHref,
-					paramValuesId,
-					null,
-					indices);
-				indices[0] = paramValues.Add(objParam);
-				if(paramHref != 0) 
-				{
-					RecordFixup(paramValuesId, paramHref, paramValues.ToArray(), null, null, null, indices);
-				}
-				else if(paramId != 0) 
+				int i = 0;
+				int initialDepth = xmlReader.Depth;
+				xmlReader.Read();
+				while(xmlReader.Depth > initialDepth) 
 				{
-//					RegisterObject(paramId, objParam, null, paramValuesId, null, indices);
+					long paramId, paramHref;
+					object objParam = null;
+					paramNames.Add (xmlReader.Name);
+					Type paramType = null;
+					
+					if (message.ParamTypes != null) {
+						if (i >= message.ParamTypes.Length)
+							throw new SerializationException ("Not enough parameter types in SoapMessages");
+						paramType = message.ParamTypes [i];
+					}
+					
+					indices[0] = i;
+					objParam = DeserializeComponent(
+						paramType,
+						out paramId,
+						out paramHref,
+						paramValuesId,
+						null,
+						indices);
+					indices[0] = paramValues.Add(objParam);
+					if(paramHref != 0) 
+					{
+						RecordFixup(paramValuesId, paramHref, paramValues.ToArray(), null, null, null, indices);
+					}
+					else if(paramId != 0) 
+					{
+	//					RegisterObject(paramId, objParam, null, paramValuesId, null, indices);
+					}
+					else 
+					{
+					}
+					i++;
 				}
-				else 
-				{
-				}
-				i++;
+				xmlReader.ReadEndElement();
+			}
+			else
+			{
+				xmlReader.Read();
 			}
 
 			message.ParamNames = (string[]) paramNames.ToArray(typeof(string));
 			message.ParamValues = paramValues.ToArray();
-			xmlReader.ReadEndElement();
 			RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);
 			return true;
 		}


More information about the Mono-devel-list mailing list