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)
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));
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);
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 {
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));
[DataMember]
public X Field;
}
+
+[CollectionDataContract (Name = "NAME", Namespace = "urn:foo", ItemName = "ITEM", KeyName = "KEY", ValueName = "VALUE")]
+public class MyDictionary<K,V> : Dictionary<K,V>
+{
+}