2009-03-12 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 12 Mar 2009 09:29:40 +0000 (09:29 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 12 Mar 2009 09:29:40 +0000 (09:29 -0000)
* SerializationMap.cs, KnownTypeCollection.cs :
  support CollectionDataContract-based dictionary too.

* XmlObjectSerializerTest.cs : added test for dictionary with
  CollectionDataContractAttribute.

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

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/SerializationMap.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/ChangeLog
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XmlObjectSerializerTest.cs

index 3f7ef97d60d6925a2cd98237f74c86e38f6d61ea..90d60b5f3d65237f94653bd1657cce0ad6a6c03f 100755 (executable)
@@ -1,3 +1,8 @@
+2009-03-12  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SerializationMap.cs, KnownTypeCollection.cs :
+         support CollectionDataContract-based dictionary too.
+
 2009-03-12  Atsushi Enomoto  <atsushi@ximian.com>
 
        * SerializationMap.cs, KnownTypeCollection.cs :
index 4ce0c05c457a1522b5e4a721448f2d567b9058e5..c7c59622be26015390b805693b94dbdf82a6eed6 100644 (file)
@@ -555,10 +555,10 @@ namespace System.Runtime.Serialization
                        if (RegisterIXmlSerializable (type) != null)
                                return true;
 
-                       if (RegisterCollectionContract (type) != null)
+                       if (RegisterDictionary (type) != null)
                                return true;
 
-                       if (RegisterDictionary (type) != null)
+                       if (RegisterCollectionContract (type) != null)
                                return true;
 
                        if (RegisterCollection (type) != null)
@@ -635,13 +635,16 @@ namespace System.Runtime.Serialization
                        return ret;
                }
 
+               // it also supports contract-based dictionary.
                private DictionaryTypeMap RegisterDictionary (Type type)
                {
                        if (!type.GetInterfaces ().Any (t => t == typeof (IDictionary) || t.FullName.StartsWith ("System.Collections.Generic.IDictionary")))
                                return null;
 
+                       var cdca = GetAttribute<CollectionDataContractAttribute> (type);
+
                        DictionaryTypeMap ret =
-                               new DictionaryTypeMap (type, this);
+                               new DictionaryTypeMap (type, cdca, this);
 
                        if (FindUserMap (ret.XmlName) != null)
                                throw new InvalidOperationException (String.Format ("Failed to add type {0} to known type collection. There already is a registered type for XML name {1}", type, ret.XmlName));
index bd8defd480f0c9ff620fe80445547e8f39e51d2d..aef83e31de296113ea9307ee2d92cd9134b5984f 100644 (file)
@@ -668,13 +668,16 @@ namespace System.Runtime.Serialization
        internal class DictionaryTypeMap : SerializationMap, ICollectionTypeMap
        {
                Type key_type, value_type;
-               internal QName dict_qname, item_qname, key_qname, value_qname;
+               QName dict_qname, item_qname, key_qname, value_qname;
                MethodInfo add_method;
+               CollectionDataContractAttribute a;
 
                public DictionaryTypeMap (
-                       Type type, KnownTypeCollection knownTypes)
+                       Type type, CollectionDataContractAttribute a, KnownTypeCollection knownTypes)
                        : base (type, QName.Empty, knownTypes)
                {
+                       this.a = a;
+
                        key_type = typeof (object);
                        value_type = typeof (object);
 
@@ -700,42 +703,42 @@ namespace System.Runtime.Serialization
                        value_qname = GetValueQName ();
                }
 
+               string ContractNamespace {
+                       get { return a != null && !String.IsNullOrEmpty (a.Namespace) ? a.Namespace : KnownTypeCollection.MSArraysNamespace; }
+               }
+
                public Type KeyType { get { return key_type; } }
                public Type ValueType { get { return value_type; } }
 
                static readonly QName kvpair_key_qname = new QName ("Key", KnownTypeCollection.MSArraysNamespace);
-               static readonly QName dentry_key_qname = new QName ("key", KnownTypeCollection.MSArraysNamespace);
                static readonly QName kvpair_value_qname = new QName ("Value", KnownTypeCollection.MSArraysNamespace);
-               static readonly QName dentry_value_qname = new QName ("value", KnownTypeCollection.MSArraysNamespace);
 
                internal virtual QName GetDictionaryQName ()
                {
-                       if (dict_qname == null)
-                               dict_qname = new QName ("ArrayOf" + GetItemQName ().Name, KnownTypeCollection.MSArraysNamespace);
-                       return dict_qname;
+                       if (a != null && !String.IsNullOrEmpty (a.Name))
+                               return new QName (a.Name, ContractNamespace);
+                       return new QName ("ArrayOf" + GetItemQName ().Name, KnownTypeCollection.MSArraysNamespace);
                }
 
                internal virtual QName GetItemQName ()
                {
-                       if (item_qname == null)
-                               item_qname = new QName ("KeyValueOf" + KnownTypes.GetQName (key_type).Name + KnownTypes.GetQName (value_type).Name, KnownTypeCollection.MSArraysNamespace);
-                       return item_qname;
+                       if (a != null && !String.IsNullOrEmpty (a.ItemName))
+                               return new QName (a.ItemName, ContractNamespace);
+                       return new QName ("KeyValueOf" + KnownTypes.GetQName (key_type).Name + KnownTypes.GetQName (value_type).Name, KnownTypeCollection.MSArraysNamespace);
                }
 
                internal virtual QName GetKeyQName ()
                {
-                       if (add_method != null)
-                               return kvpair_key_qname;
-                       else
-                               return dentry_key_qname;
+                       if (a != null && !String.IsNullOrEmpty (a.KeyName))
+                               return new QName (a.KeyName, ContractNamespace);
+                       return kvpair_key_qname;
                }
 
                internal virtual QName GetValueQName ()
                {
-                       if (add_method != null)
-                               return kvpair_value_qname;
-                       else
-                               return dentry_value_qname;
+                       if (a != null && !String.IsNullOrEmpty (a.ValueName))
+                               return new QName (a.ValueName, ContractNamespace);
+                       return kvpair_value_qname;
                }
 
                internal virtual string CurrentNamespace {
index 46bc292322943083c5e80756b97cb4b3ef954fb9..e7aed19c034900c63d1b0103f62b9fcb5b28818b 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-12  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlObjectSerializerTest.cs : added test for dictionary with
+         CollectionDataContractAttribute.
+
 2009-03-12  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XmlObjectSerializerTest.cs : added tests for IDictionary
index 98844e5ffa2a083f1a0e2fd014e7d00383822ddd..8c8be27370c3e697c8c201719b15e48d9eb4d8d3 100644 (file)
@@ -1164,6 +1164,23 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.AreEqual ("bar", d ["foo"], "#3");
                }
 
+               [Test]
+               public void CollectionContarctDictionarySerialization ()
+               {
+                       string xml = @"<?xml version='1.0' encoding='utf-16'?><NAME xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='urn:foo'><ITEM><KEY>foo</KEY><VALUE>bar</VALUE></ITEM></NAME>".Replace ('\'', '"');
+
+                       var ds = new DataContractSerializer (typeof (MyDictionary<string,string>));
+                       var d = new MyDictionary<string,string> ();
+                       d ["foo"] = "bar";
+                       var sw = new StringWriter ();
+                       using (var xw = XmlWriter.Create (sw))
+                               ds.WriteObject (xw, d);
+                       Assert.AreEqual (xml, sw.ToString (), "#1");
+                       d = (MyDictionary<string,string>) ds.ReadObject (XmlReader.Create (new StringReader (xml)));
+                       Assert.AreEqual (1, d.Count, "#2");
+                       Assert.AreEqual ("bar", d ["foo"], "#3");
+               }
+
                private T Deserialize<T> (string xml)
                {
                        return Deserialize<T> (xml, typeof (T));
@@ -1446,3 +1463,8 @@ class Foo<X,Y,Z>
        [DataMember]
        public X Field;
 }
+
+[CollectionDataContract (Name = "NAME", Namespace = "urn:foo", ItemName = "ITEM", KeyName = "KEY", ValueName = "VALUE")]
+public class MyDictionary<K,V> : Dictionary<K,V>
+{
+}