exists (and raises InvalidOperationException if required).
*/
- internal abstract class SerializationMap
+ internal abstract partial class SerializationMap
{
public const BindingFlags AllInstanceFlags =
BindingFlags.Public | BindingFlags.NonPublic |
{
KnownTypes = knownTypes;
RuntimeType = type;
- if (qname.Namespace == String.Empty)
+ if (qname.Namespace == null)
qname = new QName (qname.Name,
- "http://schemas.datacontract.org/2004/07/" + type.Namespace);
+ KnownTypeCollection.DefaultClrNamespaceBase + type.Namespace);
XmlName = qname;
Members = new List<DataMemberInfo> ();
+
+ foreach (var mi in type.GetMethods (AllInstanceFlags)) {
+ if (mi.GetCustomAttributes (typeof (OnDeserializingAttribute), false).Length > 0)
+ OnDeserializing = mi;
+ else if (mi.GetCustomAttributes (typeof (OnDeserializedAttribute), false).Length > 0)
+ OnDeserialized = mi;
+ }
}
+ public MethodInfo OnDeserializing { get; set; }
+ public MethodInfo OnDeserialized { get; set; }
+
public virtual bool OutputXsiType {
get { return true; }
}
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);
XmlFormatterDeserializer deserializer, bool empty)
{
object instance = FormatterServices.GetUninitializedObject (RuntimeType);
+
+ if (OnDeserializing != null)
+ OnDeserializing.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
+
int depth = reader.NodeType == XmlNodeType.None ? reader.Depth : reader.Depth - 1;
bool [] filled = new bool [Members.Count];
int memberInd = -1, ordered = -1;
if (Members [i].Order >= 0)
break;
if (reader.LocalName == Members [i].XmlName &&
- reader.NamespaceURI == Members [i].XmlRootNamespace) {
+ (Members [i].XmlRootNamespace == null || reader.NamespaceURI == Members [i].XmlRootNamespace)) {
memberInd = i;
dmi = Members [i];
break;
if (dmi != null)
break;
if (reader.LocalName == Members [i].XmlName &&
- reader.NamespaceURI == Members [i].XmlRootNamespace) {
+ (Members [i].XmlRootNamespace == null || reader.NamespaceURI == Members [i].XmlRootNamespace)) {
memberInd = i;
ordered = i;
dmi = Members [i];
if (!filled [i] && Members [i].IsRequired)
throw MissingRequiredMember (Members [i], reader);
+ if (OnDeserialized != null)
+ OnDeserialized.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
+
return instance;
}
}
}
- internal class XmlSerializableMap : SerializationMap
+ internal partial class XmlSerializableMap : SerializationMap
{
public XmlSerializableMap (Type type, QName qname, KnownTypeCollection knownTypes)
: base (type, qname, knownTypes)
public override object DeserializeObject (XmlReader reader, XmlFormatterDeserializer deserializer)
{
- IXmlSerializable ixs = (IXmlSerializable) FormatterServices.GetUninitializedObject (RuntimeType);
+#if NET_2_1
+ IXmlSerializable ixs = (IXmlSerializable) Activator.CreateInstance (RuntimeType);
+#else
+ IXmlSerializable ixs = (IXmlSerializable) Activator.CreateInstance (RuntimeType, true);
+#endif
ixs.ReadXml (reader);
return ixs;
}
#endif
}
- internal class SharedContractMap : SerializationMap
+ internal partial class SharedContractMap : SerializationMap
{
public SharedContractMap (
Type type, QName qname, KnownTypeCollection knownTypes)
GetDataMemberAttribute (fi);
if (dma == null)
continue;
- if (fi.IsInitOnly)
- throw new InvalidDataContractException (String.Format (
- "DataMember field {0} must not be read-only.", fi));
data_members.Add (CreateDataMemberInfo (dma, fi, fi.FieldType));
}
}
}
- internal class DefaultTypeMap : SerializationMap
+ internal partial class DefaultTypeMap : SerializationMap
{
public DefaultTypeMap (Type type, KnownTypeCollection knownTypes)
- : base (type, KnownTypeCollection.GetContractQName (type, null, null), knownTypes)
+ : base (type, KnownTypeCollection.GetStaticQName (type), knownTypes)
{
Members.AddRange (GetDefaultMembers ());
}
// FIXME: it still needs to consider ItemName/KeyName/ValueName
// (especially Dictionary collection is not likely considered yet.)
- internal class CollectionContractTypeMap : CollectionTypeMap
+ internal partial class CollectionContractTypeMap : CollectionTypeMap
{
+ CollectionDataContractAttribute a;
+
public CollectionContractTypeMap (
Type type, CollectionDataContractAttribute a, Type elementType,
QName qname, KnownTypeCollection knownTypes)
: base (type, elementType, qname, knownTypes)
{
+ this.a = a;
IsReference = a.IsReference;
}
{
}
- internal class CollectionTypeMap : SerializationMap, ICollectionTypeMap
+ internal partial class CollectionTypeMap : SerializationMap, ICollectionTypeMap
{
Type element_type;
internal QName element_qname;
public override object DeserializeEmptyContent (XmlReader reader, XmlFormatterDeserializer deserializer)
{
- return CreateInstance ();
+ var instance = CreateInstance ();
+ if (OnDeserializing != null)
+ OnDeserializing.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
+ try {
+ if (RuntimeType.IsArray)
+ return ((ArrayList)instance).ToArray (element_type);
+ else
+ return instance;
+ } finally {
+ if (OnDeserialized != null)
+ OnDeserialized.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
+ }
}
public override object DeserializeContent (XmlReader reader, XmlFormatterDeserializer deserializer)
{
object instance = CreateInstance ();
+ if (OnDeserializing != null)
+ OnDeserializing.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
int depth = reader.NodeType == XmlNodeType.None ? reader.Depth : reader.Depth - 1;
while (reader.NodeType == XmlNodeType.Element && reader.Depth > depth) {
object elem = deserializer.Deserialize (element_type, reader);
throw new NotImplementedException (String.Format ("Type {0} is not supported", RuntimeType));
reader.MoveToContent ();
}
- if (RuntimeType.IsArray)
- return ((ArrayList)instance).ToArray (element_type);
- return instance;
+ try {
+ if (RuntimeType.IsArray)
+ return ((ArrayList)instance).ToArray (element_type);
+ return instance;
+ } finally {
+ if (OnDeserialized != null)
+ OnDeserialized.Invoke (instance, new object [] {new StreamingContext (StreamingContextStates.All)});
+ }
}
public override List<DataMemberInfo> GetMembers ()
#endif
}
- internal class DictionaryTypeMap : SerializationMap, ICollectionTypeMap
+ internal partial class DictionaryTypeMap : SerializationMap, ICollectionTypeMap
{
Type key_type, value_type;
- QName dict_qname, item_qname, key_qname, value_qname;
+ QName item_qname, key_qname, value_qname;
MethodInfo add_method;
CollectionDataContractAttribute a;
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 kvpair_value_qname = new QName ("Value", KnownTypeCollection.MSArraysNamespace);
-
internal virtual QName GetDictionaryQName ()
{
- if (a != null && !String.IsNullOrEmpty (a.Name))
- return new QName (a.Name, ContractNamespace);
- return new QName ("ArrayOf" + GetItemQName ().Name, KnownTypeCollection.MSArraysNamespace);
+ string name = a != null ? a.Name : null;
+ string ns = a != null ? a.Namespace : null;
+ if (RuntimeType.IsGenericType && RuntimeType.GetGenericTypeDefinition () != typeof (Dictionary<,>))
+ name = name ?? KnownTypeCollection.GetDefaultName (RuntimeType);
+ else
+ name = "ArrayOf" + GetItemQName ().Name;
+ ns = ns ?? KnownTypeCollection.MSArraysNamespace;
+
+ return new QName (name, ns);
}
internal virtual QName GetItemQName ()
{
- 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);
+ string name = a != null ? a.ItemName : null;
+ string ns = a != null ? a.Namespace : null;
+
+ name = name ?? "KeyValueOf" + KnownTypes.GetQName (key_type).Name + KnownTypes.GetQName (value_type).Name;
+ ns = ns ?? (a != null ? ContractNamespace : KnownTypeCollection.MSArraysNamespace);
+
+ return new QName (name, ns);
}
internal virtual QName GetKeyQName ()
{
- if (a != null && !String.IsNullOrEmpty (a.KeyName))
- return new QName (a.KeyName, ContractNamespace);
- return kvpair_key_qname;
+ string name = a != null ? a.KeyName : null;
+ string ns = a != null ? a.Namespace : null;
+
+ name = name ?? "Key";
+ ns = ns ?? (a != null ? ContractNamespace : KnownTypeCollection.MSArraysNamespace);
+ return new QName (name, ns);
}
internal virtual QName GetValueQName ()
{
- if (a != null && !String.IsNullOrEmpty (a.ValueName))
- return new QName (a.ValueName, ContractNamespace);
- return kvpair_value_qname;
+ string name = a != null ? a.ValueName : null;
+ string ns = a != null ? a.Namespace : null;
+
+ name = name ?? "Value";
+ ns = ns ?? (a != null ? ContractNamespace : KnownTypeCollection.MSArraysNamespace);
+ return new QName (name, ns);
}
internal virtual string CurrentNamespace {
#endif
}
- internal class SharedTypeMap : SerializationMap
+ internal partial class SharedTypeMap : SerializationMap
{
public SharedTypeMap (
Type type, QName qname, KnownTypeCollection knownTypes)
: base (type, qname, knownTypes)
{
- Members = GetMembers (type, XmlName, false);
+ }
+
+ public void Initialize ()
+ {
+ Members = GetMembers (RuntimeType, XmlName, false);
}
List<DataMemberInfo> GetMembers (Type type, QName qname, bool declared_only)
}
}
- internal class EnumMap : SerializationMap
+ internal partial class EnumMap : SerializationMap
{
List<EnumMemberInfo> enum_members;
bool flag_attr;