2009-03-11 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Wed, 11 Mar 2009 15:03:02 +0000 (15:03 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Wed, 11 Mar 2009 15:03:02 +0000 (15:03 -0000)
* XmlFormatterSerializer.cs, XmlObjectSerializer.cs,
  XmlFormatterDeserializer.cs, KnownTypeCollection.cs :
  add more xsi:type to cover collection items.

* XmlObjectSerializerTest.cs : test for generic IList of
  DictionaryEntry. (no Hashtable serialization yet.)

svn path=/trunk/mcs/; revision=129068

mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterDeserializer.cs
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlObjectSerializer.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/ChangeLog
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XmlObjectSerializerTest.cs

index c9794c59d11dbee44eb5c890edfacd6cc41bcb84..c72acb7ab1fbf34afe3579ee262babeca9794f12 100755 (executable)
@@ -1,3 +1,9 @@
+2009-03-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlFormatterSerializer.cs, XmlObjectSerializer.cs,
+         XmlFormatterDeserializer.cs, KnownTypeCollection.cs :
+         add more xsi:type to cover collection items.
+
 2009-03-11  Atsushi Enomoto  <atsushi@ximian.com>
 
        * KnownTypeCollection.cs : fix generic argument names in xml.
index 808b7089df176549cdd1de4ebf232381e43593ac..2615c6bba63ca13fda70f521e190b0f6c1faf5e2 100644 (file)
@@ -79,6 +79,8 @@ namespace System.Runtime.Serialization
                        "http://schemas.microsoft.com/2003/10/Serialization/";
                internal const string MSArraysNamespace =
                        "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
+               internal const string DefaultClrNamespaceBase =
+                       "http://schemas.datacontract.org/2004/07/";
 
                static QName any_type, bool_type,
                        byte_type, date_type, decimal_type, double_type,
@@ -462,7 +464,7 @@ namespace System.Runtime.Serialization
                                }
                        }
                        if (ns == null)
-                               ns = XmlObjectSerializer.DefaultNamespaceBase + type.Namespace;
+                               ns = DefaultClrNamespaceBase + type.Namespace;
                        return new QName (name, ns);
                }
 
@@ -481,7 +483,7 @@ namespace System.Runtime.Serialization
                        }
 
                        if (ns == null)
-                               ns = XmlObjectSerializer.DefaultNamespaceBase + type.Namespace;
+                               ns = DefaultClrNamespaceBase + type.Namespace;
 
                        if (name == null)
                                name = type.Namespace == null || type.Namespace.Length == 0 ? type.Name : type.FullName.Substring (type.Namespace.Length + 1).Replace ('+', '.');
@@ -511,7 +513,7 @@ namespace System.Runtime.Serialization
                                foreach (var t in type.GetGenericArguments ())
                                        xmlName += GetQName (t).Name; // FIXME: check namespaces too
                        }
-                       string xmlNamespace = XmlObjectSerializer.DefaultNamespaceBase + type.Namespace;
+                       string xmlNamespace = DefaultClrNamespaceBase + type.Namespace;
                        var x = GetAttribute<XmlRootAttribute> (type);
                        if (x != null) {
                                xmlName = x.ElementName;
index b1b2744081a11ec0eb67dd193282286222578a50..e548975f3ff06f3e9c3ca71102d615783393ddca 100644 (file)
@@ -168,11 +168,25 @@ namespace System.Runtime.Serialization
                        }
 
                        SerializationMap map = types.FindUserMap (name);
+                       if (map == null && name.Namespace.StartsWith (KnownTypeCollection.DefaultClrNamespaceBase, StringComparison.Ordinal)) {
+                               var it = GetTypeFromNamePair (name.Name, name.Namespace.Substring (KnownTypeCollection.DefaultClrNamespaceBase.Length));
+                               if (types.TryRegister (it))
+                                       map = types.FindUserMap (name);
+                       }
                        if (map == null)
-                               throw new SerializationException (String.Format ("Unknown type {0} is used for DataContract. Any derived types of a data contract or a data member should be added to KnownTypes.", type));
+                               throw new SerializationException (String.Format ("Unknown type {0} is used for DataContract with reference of name {1}. Any derived types of a data contract or a data member should be added to KnownTypes.", type, name));
 
                        return map.DeserializeContent (reader, this);
                }
+
+               Type GetTypeFromNamePair (string name, string ns)
+               {
+                       foreach (var ass in AppDomain.CurrentDomain.GetAssemblies ())
+                               foreach (var t in ass.GetTypes ())
+                                       if (t.Name == name && t.Namespace == ns)
+                                               return t;
+                       return null;
+               }
        }
 }
 #endif
index d97a2e707462f67d999fe3f6fd4a7896c11d4f9a..a3364899e6db8ef892478312d4b1f4fbe2a63eed 100644 (file)
@@ -88,6 +88,21 @@ namespace System.Runtime.Serialization
                                writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true");
                        else {
                                Type actualType = graph.GetType ();
+                               if (actualType != type) {
+                                       QName qname = types.GetXmlName (actualType);
+                                       string name = qname.Name;
+                                       string ns = qname.Namespace;
+                                       if (qname == QName.Empty) {
+                                               name = XmlConvert.EncodeLocalName (actualType.Name);
+                                               ns = KnownTypeCollection.DefaultClrNamespaceBase + actualType.Namespace;
+                                       } else if (qname.Namespace == KnownTypeCollection.MSSimpleNamespace)
+                                               ns = XmlSchema.Namespace;
+                                       if (writer.LookupPrefix (ns) == null) // it goes first (extraneous, but it makes att order compatible)
+                                               writer.WriteXmlnsAttribute (null, ns);
+                                       writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
+                                       writer.WriteQualifiedName (name, ns);
+                                       writer.WriteEndAttribute ();
+                               }
                                QName predef = KnownTypeCollection.GetPredefinedTypeName (actualType);
                                if (predef != QName.Empty)
                                        SerializePrimitive (type, graph, predef);
@@ -116,13 +131,6 @@ namespace System.Runtime.Serialization
                        writer.WriteEndElement ();
                }
 
-               private void Write_i_type (QName qname)
-               {
-                       writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
-                       writer.WriteQualifiedName (qname.Name, qname.Namespace);
-                       writer.WriteEndAttribute ();
-               }
-
                public void SerializeNonPrimitive (Type type, object graph)
                {
                        Type actualType = graph.GetType ();
@@ -132,10 +140,7 @@ namespace System.Runtime.Serialization
                                /* Unknown actual type */
                                types.Add (actualType);
                                map = types.FindUserMap (actualType);
-//                             throw new InvalidDataContractException (String.Format ("Type {0} has neither Serializable nor DataContract attributes.", type));
                        }
-                       if (type != actualType)
-                               Write_i_type (map.XmlName);
 
                        map.Serialize (graph, this);
                }
index fd1a81d1cf9c7b8a22bfd18cf311395b9604ef96..9c0319d943382ef8b982633dbfe375cf037e64bf 100644 (file)
@@ -40,9 +40,6 @@ namespace System.Runtime.Serialization
 {
        public abstract class XmlObjectSerializer
        {
-               internal const string DefaultNamespaceBase =
-                       "http://schemas.datacontract.org/2004/07/";
-
                // This is only for compatible mode.
                IDataContractSurrogate surrogate;
 
index f88321a978398b79b789fd877cb80bd87291dfa5..ef66c700597406e559e4f5b32429c6310268f516 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlObjectSerializerTest.cs : test for generic IList of
+         DictionaryEntry. (no Hashtable serialization yet.)
+
 2009-03-11  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XmlObjectSerializerTest.cs : test for generic IList of KeyValuePair
index 9c4b3c373105263e57f2a9b2afa1747de846d273..f97bb4df56514c6c71e74617209c0ad786c854d8 100644 (file)
@@ -1116,6 +1116,24 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.AreEqual ("bar", d [0].Value);
                }
 
+               [Test]
+               public void GenericListOfDictionaryEntrySerialization ()
+               {
+                       string xml = @"<?xml version='1.0' encoding='utf-16'?><ArrayOfDictionaryEntry xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.datacontract.org/2004/07/System.Collections'><DictionaryEntry><_key xmlns:d3p1='http://www.w3.org/2001/XMLSchema' i:type='d3p1:string'>foo</_key><_value xmlns:d3p1='http://www.w3.org/2001/XMLSchema' i:type='d3p1:string'>bar</_value></DictionaryEntry></ArrayOfDictionaryEntry>".Replace ('\'', '"');
+
+                       var ds = new DataContractSerializer (typeof (List<DictionaryEntry>));
+                       var d = new List<DictionaryEntry> ();
+                       d.Add (new DictionaryEntry ("foo", "bar"));
+                       var sw = new StringWriter ();
+                       using (var xw = XmlWriter.Create (sw))
+                               ds.WriteObject (xw, d);
+                       Assert.AreEqual (xml, sw.ToString (), "#1");
+                       Assert.IsTrue (sw.ToString ().IndexOf ("i:type") >= 0);
+                       d = (List<DictionaryEntry>) ds.ReadObject (XmlReader.Create (new StringReader (xml)));
+                       Assert.AreEqual (1, d.Count, "#2");
+                       Assert.AreEqual ("bar", d [0].Value);
+               }
+
                private T Deserialize<T> (string xml)
                {
                        return Deserialize<T> (xml, typeof (T));