+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.
"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,
}
}
if (ns == null)
- ns = XmlObjectSerializer.DefaultNamespaceBase + type.Namespace;
+ ns = DefaultClrNamespaceBase + type.Namespace;
return new QName (name, ns);
}
}
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 ('+', '.');
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;
}
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
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);
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 ();
/* 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);
}
{
public abstract class XmlObjectSerializer
{
- internal const string DefaultNamespaceBase =
- "http://schemas.datacontract.org/2004/07/";
-
// This is only for compatible mode.
IDataContractSurrogate surrogate;
+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
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));