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)
497 // Demand the serialization formatter permission every time
498 Globals.SerializationFormatterPermission.Demand();
499 obj.GetObjectData(serInfo, context);
502 public void WriteISerializable(XmlWriterDelegator xmlWriter, ISerializable obj)
504 Type objType = obj.GetType();
505 SerializationInfo serInfo = new SerializationInfo(objType, XmlObjectSerializer.FormatterConverter, !this.UnsafeTypeForwardingEnabled);
506 GetObjectData(obj, serInfo, GetStreamingContext());
508 if (!this.UnsafeTypeForwardingEnabled && serInfo.AssemblyName == Globals.MscorlibAssemblyName)
510 // Throw if a malicious type tries to set its assembly name to "0" to get deserialized in mscorlib
511 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ISerializableAssemblyNameSetToZero, DataContract.GetClrTypeFullName(obj.GetType()))));
514 WriteSerializationInfo(xmlWriter, objType, serInfo);
517 internal void WriteSerializationInfo(XmlWriterDelegator xmlWriter, Type objType, SerializationInfo serInfo)
519 if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName)
521 if (DataContractResolver != null)
523 XmlDictionaryString typeName, typeNs;
524 if (ResolveType(serInfo.ObjectType, objType, out typeName, out typeNs))
526 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, typeName, typeNs);
531 string typeName, typeNs;
532 DataContract.GetDefaultStableName(serInfo.FullTypeName, out typeName, out typeNs);
533 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(typeName), DataContract.GetClrTypeString(typeNs));
537 WriteClrTypeInfo(xmlWriter, objType, serInfo);
538 IncrementItemCount(serInfo.MemberCount);
539 foreach (SerializationEntry serEntry in serInfo)
541 XmlDictionaryString name = DataContract.GetClrTypeString(DataContract.EncodeLocalName(serEntry.Name));
542 xmlWriter.WriteStartElement(name, DictionaryGlobals.EmptyString);
543 object obj = serEntry.Value;
545 WriteNull(xmlWriter);
547 InternalSerializeReference(xmlWriter, obj, false /*isDeclaredType*/, false /*writeXsiType*/, -1, Globals.TypeOfObject.TypeHandle);
548 xmlWriter.WriteEndElement();
552 public void WriteExtensionData(XmlWriterDelegator xmlWriter, ExtensionDataObject extensionData, int memberIndex)
554 if (IgnoreExtensionDataObject || extensionData == null)
557 IList<ExtensionDataMember> members = extensionData.Members;
560 for (int i = 0; i < extensionData.Members.Count; i++)
562 ExtensionDataMember member = extensionData.Members[i];
563 if (member.MemberIndex == memberIndex)
565 WriteExtensionDataMember(xmlWriter, member);
571 void WriteExtensionDataMember(XmlWriterDelegator xmlWriter, ExtensionDataMember member)
573 xmlWriter.WriteStartElement(member.Name, member.Namespace);
574 IDataNode dataNode = member.Value;
575 WriteExtensionDataValue(xmlWriter, dataNode);
576 xmlWriter.WriteEndElement();
579 internal virtual void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode)
581 if (dataNode.DataContractName != null)
582 WriteTypeInfo(xmlWriter, dataNode.DataContractName, dataNode.DataContractNamespace);
584 WriteClrTypeInfo(xmlWriter, dataNode.DataType, dataNode.ClrTypeName, dataNode.ClrAssemblyName);
587 internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode dataNode)
589 IncrementItemCount(1);
590 if (dataNode == null)
592 WriteNull(xmlWriter);
596 if (dataNode.PreservesReferences
597 && OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/))
600 Type dataType = dataNode.DataType;
601 if (dataType == Globals.TypeOfClassDataNode)
602 WriteExtensionClassData(xmlWriter, (ClassDataNode)dataNode);
603 else if (dataType == Globals.TypeOfCollectionDataNode)
604 WriteExtensionCollectionData(xmlWriter, (CollectionDataNode)dataNode);
605 else if (dataType == Globals.TypeOfXmlDataNode)
606 WriteExtensionXmlData(xmlWriter, (XmlDataNode)dataNode);
607 else if (dataType == Globals.TypeOfISerializableDataNode)
608 WriteExtensionISerializableData(xmlWriter, (ISerializableDataNode)dataNode);
611 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
613 if (dataType == Globals.TypeOfObject)
615 // NOTE: serialize value in DataNode<object> since it may contain non-primitive
616 // deserialized object (ex. empty class)
617 object o = dataNode.Value;
619 InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, o.GetType().TypeHandle);
622 xmlWriter.WriteExtensionData(dataNode);
624 if (dataNode.PreservesReferences)
625 OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/);
628 internal bool TryWriteDeserializedExtensionData(XmlWriterDelegator xmlWriter, IDataNode dataNode)
630 object o = dataNode.Value;
634 Type declaredType = (dataNode.DataContractName == null) ? o.GetType() : Globals.TypeOfObject;
635 InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, declaredType.TypeHandle);
639 void WriteExtensionClassData(XmlWriterDelegator xmlWriter, ClassDataNode dataNode)
641 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
643 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
645 IList<ExtensionDataMember> members = dataNode.Members;
648 for (int i = 0; i < members.Count; i++)
650 WriteExtensionDataMember(xmlWriter, members[i]);
656 void WriteExtensionCollectionData(XmlWriterDelegator xmlWriter, CollectionDataNode dataNode)
658 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
660 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
662 WriteArraySize(xmlWriter, dataNode.Size);
664 IList<IDataNode> items = dataNode.Items;
667 for (int i = 0; i < items.Count; i++)
669 xmlWriter.WriteStartElement(dataNode.ItemName, dataNode.ItemNamespace);
670 WriteExtensionDataValue(xmlWriter, items[i]);
671 xmlWriter.WriteEndElement();
677 void WriteExtensionISerializableData(XmlWriterDelegator xmlWriter, ISerializableDataNode dataNode)
679 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
681 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
683 if (dataNode.FactoryTypeName != null)
684 xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, dataNode.FactoryTypeName, dataNode.FactoryTypeNamespace);
686 IList<ISerializableDataMember> members = dataNode.Members;
689 for (int i = 0; i < members.Count; i++)
691 ISerializableDataMember member = members[i];
692 xmlWriter.WriteStartElement(member.Name, String.Empty);
693 WriteExtensionDataValue(xmlWriter, member.Value);
694 xmlWriter.WriteEndElement();
700 void WriteExtensionXmlData(XmlWriterDelegator xmlWriter, XmlDataNode dataNode)
702 if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
704 IList<XmlAttribute> xmlAttributes = dataNode.XmlAttributes;
705 if (xmlAttributes != null)
707 foreach (XmlAttribute attribute in xmlAttributes)
708 attribute.WriteTo(xmlWriter.Writer);
710 WriteExtensionDataTypeInfo(xmlWriter, dataNode);
712 IList<XmlNode> xmlChildNodes = dataNode.XmlChildNodes;
713 if (xmlChildNodes != null)
715 foreach (XmlNode node in xmlChildNodes)
716 node.WriteTo(xmlWriter.Writer);
721 protected virtual void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
723 dataContract.WriteXmlValue(xmlWriter, obj, this);
726 protected virtual void WriteNull(XmlWriterDelegator xmlWriter)
728 XmlObjectSerializer.WriteNull(xmlWriter);
731 void WriteResolvedTypeInfo(XmlWriterDelegator writer, Type objectType, Type declaredType)
733 XmlDictionaryString typeName, typeNamespace;
734 if (ResolveType(objectType, declaredType, out typeName, out typeNamespace))
736 WriteTypeInfo(writer, typeName, typeNamespace);
740 bool ResolveType(Type objectType, Type declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
742 if (!DataContractResolver.TryResolveType(objectType, declaredType, KnownTypeResolver, out typeName, out typeNamespace))
744 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedFalse, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
746 if (typeName == null)
748 if (typeNamespace == null)
754 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
757 if (typeNamespace == null)
759 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
764 protected virtual bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
766 if (!XmlObjectSerializer.IsContractDeclared(contract, declaredContract))
768 if (DataContractResolver == null)
770 WriteTypeInfo(writer, contract.Name, contract.Namespace);
775 WriteResolvedTypeInfo(writer, contract.OriginalUnderlyingType, declaredContract.OriginalUnderlyingType);
782 protected virtual void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
784 writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
787 protected virtual void WriteTypeInfo(XmlWriterDelegator writer, XmlDictionaryString dataContractName, XmlDictionaryString dataContractNamespace)
789 writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);