[Mono-devel-list] Patch to mimic MS.Net remoting name mangling

Luke Ravitch ravitch at nrtc.northrop.com
Mon May 2 16:46:12 EDT 2005


On Mon, May 02, 2005 at 09:41:06PM +0200, Lluis Sanchez wrote:
> This bug needs a more generic solution. Field names should be encoded
> using XmlConvert.EncodeLocalName, since there may be other characters in
> the name that are not valid in xml names. For inherited fields, the

Good call - this version of the patch uses EncodeLocalName instead of
hacking it myself.  Is something like this what you have in mind?

> serialized name should be "className+fieldName". The binary serializer
> already write serialized fields in this way, but the class name is not
> being added in the soap serializer (notice that "+" will be encoded to
> _002B_ by XmlConvert.EncodeLocalName).

Yeah, I figured the _x002B_ meant "+", but didn't realize that there's
a generic standardized way of doing the encoding.  I suppose I should
have thought to look.

-- 
Luke Ravitch  <ravitch at nrtc.northrop.com>   Telephone: 310-864-7478
Software Engr., Advanced Software Sys. | One Hornet Way, MS 9M52/W6
Northrop  Grumman  Integrated  Systems | El Segundo, CA 90245-23804
-------------- next part --------------
Index: mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs
===================================================================
--- mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs	(revision 43735)
+++ mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs	(working copy)
@@ -391,7 +391,9 @@
 //					bool specifyEncoding = false;
 //					if(objectData[i] != null)
 //						 specifyEncoding = (objectData[i].GetType() != fieldInfo.FieldType);
-					_xmlWriter.WriteStartElement(fieldInfo.Name);
+
+					string name = SoapReader.GetFieldName (fieldInfo, currentType);
+					_xmlWriter.WriteStartElement(name);
 					SerializeComponent(
 						objectData[i], 
 						IsEncodingNeeded(objectData[i], fieldInfo.FieldType));
Index: mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
===================================================================
--- mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	(revision 43735)
+++ mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	(working copy)
@@ -36,6 +36,7 @@
 using System.Runtime.Remoting;
 using System.Runtime.Serialization;
 using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Metadata;
 
 namespace System.Runtime.Serialization.Formatters.Soap {
 	internal sealed class SoapReader {
@@ -729,7 +730,28 @@
 					indices);
 			}
 		}
-
+
+		static public string GetFieldName (FieldInfo info, Type type)
+		{
+			string name;
+			Type attr_t = typeof (SoapFieldAttribute);
+			SoapFieldAttribute soapAttr = Attribute.GetCustomAttribute (info, attr_t) as SoapFieldAttribute;
+
+			// To maintain compatibility with MS.Net, we need to mangle the names of any
+			// private inherited members that don't have XmlElementName set in a
+			// SoapFieldAttribute.  MS.Net prepends the base class name to the field name,
+			// using "+" as a delimiter.
+
+			if ((soapAttr != null) && (soapAttr.XmlElementName != null)) {
+				name = soapAttr.XmlElementName;
+			} else if (info.IsPrivate && (info.DeclaringType != type)) {
+				name = info.DeclaringType.Name + "+" + info.Name;
+			} else {
+				name = info.Name;
+			}
+			return XmlConvert.EncodeLocalName (name);
+		}
+		
 		TypeMetadata GetTypeMetadata (Type type)
 		{
 			TypeMetadata tm = _fieldIndices[type] as TypeMetadata;
@@ -738,10 +760,14 @@
 			tm = new TypeMetadata ();
 			tm.MemberInfos = FormatterServices.GetSerializableMembers (type, _context);
 			
-			tm.Indices	= new Hashtable();
-			for(int i = 0; i < tm.MemberInfos.Length; i++) 
-				tm.Indices.Add (tm.MemberInfos[i].Name, i);
-			
+			tm.Indices = new Hashtable();
+			for (int i = 0; i < tm.MemberInfos.Length; i++) {
+				// Only fields should be serializable, so this should never be null.
+				FieldInfo fieldInfo = tm.MemberInfos[i] as FieldInfo;
+
+				tm.Indices.Add (GetFieldName (fieldInfo, type), i);
+			} 
+
 			_fieldIndices[type] = tm;
 			return tm;
 		}


More information about the Mono-devel-list mailing list