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 <[EMAIL PROTECTED]> Telephone: 310-864-7478
Software Engr., Advanced Software Sys. | One Hornet Way, MS 9M52/W6
Northrop Grumman Integrated Systems | El Segundo, CA 90245-23804
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;
}