1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.Runtime.Serialization
8 using System.Collections;
9 using System.Diagnostics;
10 using System.Globalization;
12 using System.Reflection;
15 using System.Collections.Generic;
16 using System.Xml.Serialization;
17 using System.ServiceModel.Diagnostics;
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Runtime.CompilerServices;
21 using System.Runtime.Serialization.Diagnostics;
24 public class XmlObjectSerializerWriteContext : XmlObjectSerializerContext
26 internal class XmlObjectSerializerWriteContext : XmlObjectSerializerContext
29 ObjectReferenceStack byValObjectsInScope = new ObjectReferenceStack();
30 XmlSerializableWriter xmlSerializableWriter;
31 const int depthToCheckCyclicReference = 512;
32 protected bool preserveObjectReferences;
33 ObjectToIdCache serializedObjects;
34 bool isGetOnlyCollection;
35 readonly bool unsafeTypeForwardingEnabled;
36 protected bool serializeReadOnlyTypes;
38 internal static XmlObjectSerializerWriteContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
40 return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
41 ? new XmlObjectSerializerWriteContextComplex(serializer, rootTypeDataContract, dataContractResolver)
42 : new XmlObjectSerializerWriteContext(serializer, rootTypeDataContract, dataContractResolver);
45 internal static XmlObjectSerializerWriteContext CreateContext(NetDataContractSerializer serializer, Hashtable surrogateDataContracts)
47 return new XmlObjectSerializerWriteContextComplex(serializer, surrogateDataContracts);
50 protected XmlObjectSerializerWriteContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver resolver)
51 : base(serializer, rootTypeDataContract, resolver)
53 this.serializeReadOnlyTypes = serializer.SerializeReadOnlyTypes;
54 // Known types restricts the set of types that can be deserialized
55 this.unsafeTypeForwardingEnabled = true;
58 protected XmlObjectSerializerWriteContext(NetDataContractSerializer serializer)
61 this.unsafeTypeForwardingEnabled = NetDataContractSerializer.UnsafeTypeForwardingEnabled;
64 internal XmlObjectSerializerWriteContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
65 : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
67 // Known types restricts the set of types that can be deserialized
68 this.unsafeTypeForwardingEnabled = true;
72 internal ObjectToIdCache SerializedObjects
74 protected ObjectToIdCache SerializedObjects
79 if (serializedObjects == null)
80 serializedObjects = new ObjectToIdCache();
81 return serializedObjects;
85 internal override bool IsGetOnlyCollection
87 get { return this.isGetOnlyCollection; }
88 set { this.isGetOnlyCollection = value; }
91 internal bool SerializeReadOnlyTypes
93 get { return this.serializeReadOnlyTypes; }
96 internal bool UnsafeTypeForwardingEnabled
98 get { return this.unsafeTypeForwardingEnabled; }
102 public void StoreIsGetOnlyCollection()
104 internal void StoreIsGetOnlyCollection()
107 this.isGetOnlyCollection = true;
110 public void InternalSerializeReference(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
112 if (!OnHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/))
113 InternalSerialize(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle);
114 OnEndHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/);
117 public virtual void InternalSerialize(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
121 Type declaredType = Globals.TypeOfObject;
122 SerializeWithXsiType(xmlWriter, obj, Type.GetTypeHandle(obj), null/*type*/, -1, declaredType.TypeHandle, declaredType);
124 else if (isDeclaredType)
126 DataContract contract = GetDataContract(declaredTypeID, declaredTypeHandle);
127 SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle);
131 RuntimeTypeHandle objTypeHandle = Type.GetTypeHandle(obj);
132 if (declaredTypeHandle.Equals(objTypeHandle))
134 DataContract dataContract = (declaredTypeID >= 0)
135 ? GetDataContract(declaredTypeID, declaredTypeHandle)
136 : GetDataContract(declaredTypeHandle, null /*type*/);
137 SerializeWithoutXsiType(dataContract, xmlWriter, obj, declaredTypeHandle);
141 SerializeWithXsiType(xmlWriter, obj, objTypeHandle, null /*type*/, declaredTypeID, declaredTypeHandle, Type.GetTypeFromHandle(declaredTypeHandle));
146 internal void SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
148 if (OnHandleIsReference(xmlWriter, dataContract, obj))
150 if (dataContract.KnownDataContracts != null)
152 scopedKnownTypes.Push(dataContract.KnownDataContracts);
153 WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
154 scopedKnownTypes.Pop();
158 WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
162 internal virtual void SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
164 bool verifyKnownType = false;
165 Type declaredType = rootTypeDataContract.OriginalUnderlyingType;
167 if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
169 if (DataContractResolver != null)
171 WriteResolvedTypeInfo(xmlWriter, graphType, declaredType);
174 else if (!declaredType.IsArray) //Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
176 verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, rootTypeDataContract);
178 SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, originalDeclaredTypeHandle, declaredType);
181 protected virtual void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
183 DataContract dataContract;
184 bool verifyKnownType = false;
185 if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
187 dataContract = GetDataContractSkipValidation(DataContract.GetId(objectTypeHandle), objectTypeHandle, objectType);
188 if (OnHandleIsReference(xmlWriter, dataContract, obj))
190 if (this.Mode == SerializationMode.SharedType && dataContract.IsValidContract(this.Mode))
191 dataContract = dataContract.GetValidContract(this.Mode);
193 dataContract = GetDataContract(declaredTypeHandle, declaredType);
194 if (!WriteClrTypeInfo(xmlWriter, dataContract) && DataContractResolver != null)
196 if (objectType == null)
198 objectType = Type.GetTypeFromHandle(objectTypeHandle);
200 WriteResolvedTypeInfo(xmlWriter, objectType, declaredType);
203 else if (declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
205 // A call to OnHandleIsReference is not necessary here -- arrays cannot be IsReference
206 dataContract = GetDataContract(objectTypeHandle, objectType);
207 WriteClrTypeInfo(xmlWriter, dataContract);
208 dataContract = GetDataContract(declaredTypeHandle, declaredType);
212 dataContract = GetDataContract(objectTypeHandle, objectType);
213 if (OnHandleIsReference(xmlWriter, dataContract, obj))
215 if (!WriteClrTypeInfo(xmlWriter, dataContract))
217 DataContract declaredTypeContract = (declaredTypeID >= 0)
218 ? GetDataContract(declaredTypeID, declaredTypeHandle)
219 : GetDataContract(declaredTypeHandle, declaredType);
220 verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
224 SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredTypeHandle, declaredType);
227 internal bool OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, object obj)
229 if (preserveObjectReferences || !contract.IsReference || isGetOnlyCollection)
235 int objectId = SerializedObjects.GetId(obj, ref isNew);
236 byValObjectsInScope.EnsureSetAsIsReference(obj);
239 xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.IdLocalName,
240 DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
245 xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.RefLocalName, DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
250 protected void SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, bool verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
252 bool knownTypesAddedInCurrentScope = false;
253 if (dataContract.KnownDataContracts != null)
255 scopedKnownTypes.Push(dataContract.KnownDataContracts);
256 knownTypesAddedInCurrentScope = true;
261 if (!IsKnownType(dataContract, declaredType))
263 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DcTypeNotFoundOnSerialize, DataContract.GetClrTypeFullName(dataContract.UnderlyingType), dataContract.StableName.Name, dataContract.StableName.Namespace)));
266 WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
268 if (knownTypesAddedInCurrentScope)
270 scopedKnownTypes.Pop();
274 internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
279 internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, string clrTypeName, string clrAssemblyName)
284 internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, SerializationInfo serInfo)
289 public virtual void WriteAnyType(XmlWriterDelegator xmlWriter, object value)
291 xmlWriter.WriteAnyType(value);
294 public virtual void WriteString(XmlWriterDelegator xmlWriter, string value)
296 xmlWriter.WriteString(value);
298 public virtual void WriteString(XmlWriterDelegator xmlWriter, string value, XmlDictionaryString name, XmlDictionaryString ns)
301 WriteNull(xmlWriter, typeof(string), true/*isMemberTypeSerializable*/, name, ns);
304 xmlWriter.WriteStartElementPrimitive(name, ns);
305 xmlWriter.WriteString(value);
306 xmlWriter.WriteEndElementPrimitive();
310 public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value)
312 xmlWriter.WriteBase64(value);
314 public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value, XmlDictionaryString name, XmlDictionaryString ns)
317 WriteNull(xmlWriter, typeof(byte[]), true/*isMemberTypeSerializable*/, name, ns);
320 xmlWriter.WriteStartElementPrimitive(name, ns);
321 xmlWriter.WriteBase64(value);
322 xmlWriter.WriteEndElementPrimitive();
326 public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value)
328 xmlWriter.WriteUri(value);
330 public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value, XmlDictionaryString name, XmlDictionaryString ns)
333 WriteNull(xmlWriter, typeof(Uri), true/*isMemberTypeSerializable*/, name, ns);
336 xmlWriter.WriteStartElementPrimitive(name, ns);
337 xmlWriter.WriteUri(value);
338 xmlWriter.WriteEndElementPrimitive();
342 public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value)
344 xmlWriter.WriteQName(value);
346 public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value, XmlDictionaryString name, XmlDictionaryString ns)
349 WriteNull(xmlWriter, typeof(XmlQualifiedName), true/*isMemberTypeSerializable*/, name, ns);
352 if (ns != null && ns.Value != null && ns.Value.Length > 0)
353 xmlWriter.WriteStartElement(Globals.ElementPrefix, name, ns);
355 xmlWriter.WriteStartElement(name, ns);
356 xmlWriter.WriteQName(value);
357 xmlWriter.WriteEndElement();
361 internal void HandleGraphAtTopLevel(XmlWriterDelegator writer, object obj, DataContract contract)
363 writer.WriteXmlnsAttribute(Globals.XsiPrefix, DictionaryGlobals.SchemaInstanceNamespace);
364 if (contract.IsISerializable)
365 writer.WriteXmlnsAttribute(Globals.XsdPrefix, DictionaryGlobals.SchemaNamespace);
366 OnHandleReference(writer, obj, true /*canContainReferences*/);
369 internal virtual bool OnHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
371 if (xmlWriter.depth < depthToCheckCyclicReference)
373 if (canContainCyclicReference)
375 if (byValObjectsInScope.Count == 0 && DiagnosticUtility.ShouldTraceWarning)
377 TraceUtility.Trace(TraceEventType.Warning, TraceCode.ObjectWithLargeDepth, SR.GetString(SR.TraceCodeObjectWithLargeDepth));
379 if (byValObjectsInScope.Contains(obj))
380 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotSerializeObjectWithCycles, DataContract.GetClrTypeFullName(obj.GetType()))));
381 byValObjectsInScope.Push(obj);
386 internal virtual void OnEndHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
388 if (xmlWriter.depth < depthToCheckCyclicReference)
390 if (canContainCyclicReference)
392 byValObjectsInScope.Pop(obj);
396 public void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable)
398 CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
399 WriteNull(xmlWriter);
402 internal void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable, XmlDictionaryString name, XmlDictionaryString ns)
404 xmlWriter.WriteStartElement(name, ns);
405 WriteNull(xmlWriter, memberType, isMemberTypeSerializable);
406 xmlWriter.WriteEndElement();
409 public void IncrementArrayCount(XmlWriterDelegator xmlWriter, Array array)
411 IncrementCollectionCount(xmlWriter, array.GetLength(0));
414 public void IncrementCollectionCount(XmlWriterDelegator xmlWriter, ICollection collection)
416 IncrementCollectionCount(xmlWriter, collection.Count);
419 public void IncrementCollectionCountGeneric<T>(XmlWriterDelegator xmlWriter, ICollection<T> collection)
421 IncrementCollectionCount(xmlWriter, collection.Count);
424 void IncrementCollectionCount(XmlWriterDelegator xmlWriter, int size)
426 IncrementItemCount(size);
427 WriteArraySize(xmlWriter, size);
430 internal virtual void WriteArraySize(XmlWriterDelegator xmlWriter, int size)
434 public static T GetDefaultValue<T>()
439 public static T GetNullableValue<T>(Nullable<T> value) where T : struct
441 // value.Value will throw if hasValue is false
445 public static void ThrowRequiredMemberMustBeEmitted(string memberName, Type type)
447 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.RequiredMemberMustBeEmitted, memberName, type.FullName)));
450 public static bool GetHasValue<T>(Nullable<T> value) where T : struct
452 return value.HasValue;
455 internal void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
457 if (xmlSerializableWriter == null)
458 xmlSerializableWriter = new XmlSerializableWriter();
459 WriteIXmlSerializable(xmlWriter, obj, xmlSerializableWriter);
462 internal static void WriteRootIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
464 WriteIXmlSerializable(xmlWriter, obj, new XmlSerializableWriter());
467 static void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj, XmlSerializableWriter xmlSerializableWriter)
469 xmlSerializableWriter.BeginWrite(xmlWriter.Writer, obj);
470 IXmlSerializable xmlSerializable = obj as IXmlSerializable;
471 if (xmlSerializable != null)
472 xmlSerializable.WriteXml(xmlSerializableWriter);
475 XmlElement xmlElement = obj as XmlElement;
476 if (xmlElement != null)
477 xmlElement.WriteTo(xmlSerializableWriter);
480 XmlNode[] xmlNodes = obj as XmlNode[];
481 if (xmlNodes != null)
482 foreach (XmlNode xmlNode in xmlNodes)
483 xmlNode.WriteTo(xmlSerializableWriter);
485 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownXmlType, DataContract.GetClrTypeFullName(obj.GetType()))));
488 xmlSerializableWriter.EndWrite();
491 [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISerializable",
492 Safe = "Demanding Serialization formatter permission is enough.")]
493 [SecuritySafeCritical]
494 [MethodImpl(MethodImplOptions.NoInlining)]
495 internal void GetObjectData(ISerializable obj, SerializationInfo serInfo, StreamingContext context)
498 // Demand the serialization formatter permission every time
499 Globals.SerializationFormatterPermission.Demand();
501 obj.GetObjectData(serInfo, context);
504 public void WriteISerializable(XmlWriterDelegator xmlWriter, ISerializable obj)
506 Type objType = obj.GetType();
507 SerializationInfo serInfo = new SerializationInfo(objType, XmlObjectSerializer.FormatterConverter, !this.UnsafeTypeForwardingEnabled);
508 GetObjectData(obj, serInfo, GetStreamingContext());
510 if (!this.UnsafeTypeForwardingEnabled && serInfo.AssemblyName == Globals.MscorlibAssemblyName)
512 // Throw if a malicious type tries to set its assembly name to "0" to get deserialized in mscorlib
513 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ISerializableAssemblyNameSetToZero, DataContract.GetClrTypeFullName(obj.GetType()))));
516 WriteSerializationInfo(xmlWriter, objType, serInfo);
519 internal void WriteSerializationInfo(XmlWriterDelegator xmlWriter, Type objType, SerializationInfo serInfo)
521 if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName)
523 if (DataContractResolver != null)
525 XmlDictionaryString typeName, typeNs;
526 if (ResolveType(serInfo.ObjectType, objType, out typeName, out typeNs))
528 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, typeName, typeNs);
533 string typeName, typeNs;
534 DataContract.GetDefaultStableName(serInfo.FullTypeName, out typeName, out typeNs);
535 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(typeName), DataContract.GetClrTypeString(typeNs));
539 WriteClrTypeInfo(xmlWriter, objType, serInfo);
540 IncrementItemCount(serInfo.MemberCount);
541 foreach (SerializationEntry serEntry in serInfo)
543 XmlDictionaryString name = DataContract.GetClrTypeString(DataContract.EncodeLocalName(serEntry.Name));
544 xmlWriter.WriteStartElement(name, DictionaryGlobals.EmptyString);
545 object obj = serEntry.Value;
547 WriteNull(xmlWriter);
549 InternalSerializeReference(xmlWriter, obj, false /*isDeclaredType*/, false /*writeXsiType*/, -1, Globals.TypeOfObject.TypeHandle);
550 xmlWriter.WriteEndElement();
554 public void WriteExtensionData(XmlWriterDelegator xmlWriter, ExtensionDataObject extensionData, int memberIndex)
556 if (IgnoreExtensionDataObject || extensionData == null)
559 IList<ExtensionDataMember> members = extensionData.Members;
562 for (int i = 0; i < extensionData.Members.Count; i++)
564 ExtensionDataMember member = extensionData.Members[i];
565 if (member.MemberIndex == memberIndex)
567 WriteExtensionDataMember(xmlWriter, member);
573 void WriteExtensionDataMember(XmlWriterDelegator xmlWriter, ExtensionDataMember member)
575 xmlWriter.WriteStartElement(member.Name, member.Namespace);
576 IDataNode dataNode = member.Value;
577 WriteExtensionDataValue(xmlWriter, dataNode);
578 xmlWriter.WriteEndElement();
581 internal virtual void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode)
583 if (dataNode.DataContractName != null)
584 WriteTypeInfo(xmlWriter, dataNode.DataContractName, dataNode.DataContractNamespace);
586 WriteClrTypeInfo(xmlWriter, dataNode.DataType, dataNode.ClrTypeName, dataNode.ClrAssemblyName);
589 internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode dataNode)
591 IncrementItemCount(1);
592 if (dataNode == null)
594 WriteNull(xmlWriter);
598 if (dataNode.PreservesReferences
599 && OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/))
602 Type dataType = dataNode.DataType;
603 if (dataType == Globals.TypeOfClassDataNode)
604 WriteExtensionClassData(xmlWriter, (ClassDataNode)dataNode);
605 else if (dataType == Globals.TypeOfCollectionDataNode)
606 WriteExtensionCollectionData(xmlWriter, (CollectionDataNode)dataNode);
607 else if (dataType == Globals.TypeOfXmlDataNode)
608 WriteExtensionXmlData(xmlWriter, (XmlDataNode)dataNode);
609 else if (dataType == Globals.TypeOfISerializableDataNode)
610 WriteExtensionISerializableData(xmlWriter, (ISerializableDataNode)dataNode);
613 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
615 if (dataType == Globals.TypeOfObject)
617 // NOTE: serialize value in DataNode<object> since it may contain non-primitive
618 // deserialized object (ex. empty class)
619 object o = dataNode.Value;
621 InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, o.GetType().TypeHandle);
624 xmlWriter.WriteExtensionData(dataNode);
626 if (dataNode.PreservesReferences)
627 OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/);
630 internal bool TryWriteDeserializedExtensionData(XmlWriterDelegator xmlWriter, IDataNode dataNode)
632 object o = dataNode.Value;
636 Type declaredType = (dataNode.DataContractName == null) ? o.GetType() : Globals.TypeOfObject;
637 InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, declaredType.TypeHandle);
641 void WriteExtensionClassData(XmlWriterDelegator xmlWriter, ClassDataNode dataNode)
643 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
645 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
647 IList<ExtensionDataMember> members = dataNode.Members;
650 for (int i = 0; i < members.Count; i++)
652 WriteExtensionDataMember(xmlWriter, members[i]);
658 void WriteExtensionCollectionData(XmlWriterDelegator xmlWriter, CollectionDataNode dataNode)
660 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
662 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
664 WriteArraySize(xmlWriter, dataNode.Size);
666 IList<IDataNode> items = dataNode.Items;
669 for (int i = 0; i < items.Count; i++)
671 xmlWriter.WriteStartElement(dataNode.ItemName, dataNode.ItemNamespace);
672 WriteExtensionDataValue(xmlWriter, items[i]);
673 xmlWriter.WriteEndElement();
679 void WriteExtensionISerializableData(XmlWriterDelegator xmlWriter, ISerializableDataNode dataNode)
681 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
683 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
685 if (dataNode.FactoryTypeName != null)
686 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, dataNode.FactoryTypeName, dataNode.FactoryTypeNamespace);
688 IList<ISerializableDataMember> members = dataNode.Members;
691 for (int i = 0; i < members.Count; i++)
693 ISerializableDataMember member = members[i];
694 xmlWriter.WriteStartElement(member.Name, String.Empty);
695 WriteExtensionDataValue(xmlWriter, member.Value);
696 xmlWriter.WriteEndElement();
702 void WriteExtensionXmlData(XmlWriterDelegator xmlWriter, XmlDataNode dataNode)
704 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
706 IList<XmlAttribute> xmlAttributes = dataNode.XmlAttributes;
707 if (xmlAttributes != null)
709 foreach (XmlAttribute attribute in xmlAttributes)
710 attribute.WriteTo(xmlWriter.Writer);
712 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
714 IList<XmlNode> xmlChildNodes = dataNode.XmlChildNodes;
715 if (xmlChildNodes != null)
717 foreach (XmlNode node in xmlChildNodes)
718 node.WriteTo(xmlWriter.Writer);
723 protected virtual void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
725 dataContract.WriteXmlValue(xmlWriter, obj, this);
728 protected virtual void WriteNull(XmlWriterDelegator xmlWriter)
730 XmlObjectSerializer.WriteNull(xmlWriter);
733 void WriteResolvedTypeInfo(XmlWriterDelegator writer, Type objectType, Type declaredType)
735 XmlDictionaryString typeName, typeNamespace;
736 if (ResolveType(objectType, declaredType, out typeName, out typeNamespace))
738 WriteTypeInfo(writer, typeName, typeNamespace);
742 bool ResolveType(Type objectType, Type declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
744 if (!DataContractResolver.TryResolveType(objectType, declaredType, KnownTypeResolver, out typeName, out typeNamespace))
746 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedFalse, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
748 if (typeName == null)
750 if (typeNamespace == null)
756 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
759 if (typeNamespace == null)
761 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
766 protected virtual bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
768 if (!XmlObjectSerializer.IsContractDeclared(contract, declaredContract))
770 if (DataContractResolver == null)
772 WriteTypeInfo(writer, contract.Name, contract.Namespace);
777 WriteResolvedTypeInfo(writer, contract.OriginalUnderlyingType, declaredContract.OriginalUnderlyingType);
784 protected virtual void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
786 writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
789 protected virtual void WriteTypeInfo(XmlWriterDelegator writer, XmlDictionaryString dataContractName, XmlDictionaryString dataContractNamespace)
791 writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);