public virtual void Serialize (object graph,
XmlFormatterSerializer serializer)
{
- string label = null;
- if (IsReference) {
- label = (string) serializer.References [graph];
- if (label != null) {
- serializer.Writer.WriteAttributeString ("z", "Ref", KnownTypeCollection.MSSimpleNamespace, label);
- return;
- }
- label = "i" + (serializer.References.Count + 1);
- serializer.References.Add (graph, label);
- }
+ string label;
+ if (serializer.TrySerializeAsReference (IsReference, graph, out label))
+ return;
else if (serializer.SerializingObjects.Contains (graph))
throw new SerializationException (String.Format ("Circular reference of an object in the object graph was found: '{0}' of type {1}", graph, graph.GetType ()));
serializer.SerializingObjects.Add (graph);
public static void Serialize (XmlDictionaryWriter writer, object graph,
KnownTypeCollection types,
- bool ignoreUnknown, int maxItems, string root_ns)
+ bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences)
{
- new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns)
+ new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns, preserveObjectReferences)
.Serialize (graph != null ? graph.GetType () : null, graph);
}
public XmlFormatterSerializer (XmlDictionaryWriter writer,
KnownTypeCollection types,
- bool ignoreUnknown, int maxItems, string root_ns)
+ bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences)
{
this.writer = writer;
this.types = types;
ignore_unknown = ignoreUnknown;
max_items = maxItems;
+ PreserveObjectReferences = preserveObjectReferences;
}
+ public bool PreserveObjectReferences { get; private set; }
+
public ArrayList SerializingObjects {
get { return objects; }
}
public void SerializePrimitive (Type type, object graph, QName qname)
{
+ string label;
+ if (TrySerializeAsReference (false, graph, out label))
+ return;
+ if (label != null)
+ Writer.WriteAttributeString ("z", "Id", KnownTypeCollection.MSSimpleNamespace, label);
+
// writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
// writer.WriteQualifiedName (qname.Name, qname.Namespace);
// writer.WriteEndAttribute ();
{
writer.WriteEndElement ();
}
+
+ // returned bool: whether z:Ref is written or not.
+ // out label: object label either in use or newly allocated.
+ public bool TrySerializeAsReference (bool isMapReference, object graph, out string label)
+ {
+ label = null;
+ if (!isMapReference && (!PreserveObjectReferences || graph == null || graph.GetType ().IsValueType))
+ return false;
+
+ label = (string) References [graph];
+ if (label != null) {
+ Writer.WriteAttributeString ("z", "Ref", KnownTypeCollection.MSSimpleNamespace, label);
+ label = null; // do not write label
+ return true;
+ }
+
+ label = "i" + (References.Count + 1);
+ References.Add (graph, label);
+
+ return false;
+ }
}
}
#endif
root.FDict.Add (foo2);
ds.WriteObject (ms, root);
- Console.WriteLine (Encoding.UTF8.GetString (ms.ToArray ()));
+ string result = Encoding.UTF8.GetString (ms.ToArray ());
ms.Position = 0;
root = (Root) ds.ReadObject (ms);
Assert.AreEqual (2, root.FDict.Count, "#1");
+ int idx = result.IndexOf ("foo1");
+ Assert.IsTrue (idx >= 0, "#2");
+ // since "foo1" is stored as z:Ref for string, it must not occur twice.
+ int idx2 = result.IndexOf ("foo1", idx + 1);
+ Assert.IsTrue (idx2 < 0, "idx2 should not occur at " + idx2);
}
}