1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.Runtime.Serialization
8 using System.Collections.Generic;
9 using System.Reflection;
10 using System.Runtime.Serialization.Diagnostics.Application;
11 using System.Security;
13 using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
16 public class XmlObjectSerializerContext
18 internal class XmlObjectSerializerContext
21 protected XmlObjectSerializer serializer;
22 protected DataContract rootTypeDataContract;
23 internal ScopedKnownTypes scopedKnownTypes = new ScopedKnownTypes();
24 protected DataContractDictionary serializerKnownDataContracts;
25 bool isSerializerKnownDataContractsSetExplicit;
26 protected IList<Type> serializerKnownTypeList;
28 [Fx.Tag.SecurityNote(Critical = "We base the decision whether to Demand SerializationFormatterPermission on this value.")]
30 bool demandedSerializationFormatterPermission;
32 [Fx.Tag.SecurityNote(Critical = "We base the decision whether to Demand MemberAccess on this value.")]
34 bool demandedMemberAccessPermission;
36 int maxItemsInObjectGraph;
37 StreamingContext streamingContext;
38 bool ignoreExtensionDataObject;
39 DataContractResolver dataContractResolver;
40 KnownTypeDataContractResolver knownTypeResolver;
42 internal XmlObjectSerializerContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject, DataContractResolver dataContractResolver)
44 this.serializer = serializer;
46 this.maxItemsInObjectGraph = maxItemsInObjectGraph;
47 this.streamingContext = streamingContext;
48 this.ignoreExtensionDataObject = ignoreExtensionDataObject;
49 this.dataContractResolver = dataContractResolver;
52 internal XmlObjectSerializerContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
53 : this(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject, null)
57 internal XmlObjectSerializerContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
59 serializer.MaxItemsInObjectGraph,
60 new StreamingContext(StreamingContextStates.All),
61 serializer.IgnoreExtensionDataObject,
64 this.rootTypeDataContract = rootTypeDataContract;
65 this.serializerKnownTypeList = serializer.knownTypeList;
68 internal XmlObjectSerializerContext(NetDataContractSerializer serializer)
70 serializer.MaxItemsInObjectGraph,
72 serializer.IgnoreExtensionDataObject)
76 internal virtual SerializationMode Mode
78 get { return SerializationMode.SharedContract; }
81 internal virtual bool IsGetOnlyCollection
87 [Fx.Tag.SecurityNote(Critical = "Demands SerializationFormatter permission. demanding the right permission is critical.",
88 Safe = "No data or control leaks in or out, must be callable from transparent generated IL.")]
89 [SecuritySafeCritical]
90 public void DemandSerializationFormatterPermission()
93 if (!demandedSerializationFormatterPermission)
95 Globals.SerializationFormatterPermission.Demand();
96 demandedSerializationFormatterPermission = true;
101 [Fx.Tag.SecurityNote(Critical = "Demands MemberAccess permission. demanding the right permission is critical.",
102 Safe = "No data or control leaks in or out, must be callable from transparent generated IL.")]
103 [SecuritySafeCritical]
104 public void DemandMemberAccessPermission()
107 if (!demandedMemberAccessPermission)
109 Globals.MemberAccessPermission.Demand();
110 demandedMemberAccessPermission = true;
115 public StreamingContext GetStreamingContext()
117 return streamingContext;
120 static MethodInfo incrementItemCountMethod;
121 internal static MethodInfo IncrementItemCountMethod
125 if (incrementItemCountMethod == null)
126 incrementItemCountMethod = typeof(XmlObjectSerializerContext).GetMethod("IncrementItemCount", Globals.ScanAllMembers);
127 return incrementItemCountMethod;
130 public void IncrementItemCount(int count)
132 if (count > maxItemsInObjectGraph - itemCount)
133 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ExceededMaxItemsQuota, maxItemsInObjectGraph)));
137 internal int RemainingItemCount
139 get { return maxItemsInObjectGraph - itemCount; }
142 internal bool IgnoreExtensionDataObject
144 get { return ignoreExtensionDataObject; }
147 protected DataContractResolver DataContractResolver
149 get { return dataContractResolver; }
152 protected KnownTypeDataContractResolver KnownTypeResolver
156 if (knownTypeResolver == null)
158 knownTypeResolver = new KnownTypeDataContractResolver(this);
160 return knownTypeResolver;
164 internal DataContract GetDataContract(Type type)
166 return GetDataContract(type.TypeHandle, type);
169 internal virtual DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
171 if (IsGetOnlyCollection)
173 return DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(typeHandle), typeHandle, type, Mode);
177 return DataContract.GetDataContract(typeHandle, type, Mode);
181 internal virtual DataContract GetDataContractSkipValidation(int typeId, RuntimeTypeHandle typeHandle, Type type)
183 if (IsGetOnlyCollection)
185 return DataContract.GetGetOnlyCollectionDataContractSkipValidation(typeId, typeHandle, type);
189 return DataContract.GetDataContractSkipValidation(typeId, typeHandle, type);
194 internal virtual DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
196 if (IsGetOnlyCollection)
198 return DataContract.GetGetOnlyCollectionDataContract(id, typeHandle, null /*type*/, Mode);
202 return DataContract.GetDataContract(id, typeHandle, Mode);
206 internal virtual void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
208 if (!isMemberTypeSerializable)
209 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeNotSerializable, memberType)));
212 internal virtual Type GetSurrogatedType(Type type)
217 DataContractDictionary SerializerKnownDataContracts
221 // This field must be initialized during construction by serializers using data contracts.
222 if (!this.isSerializerKnownDataContractsSetExplicit)
224 this.serializerKnownDataContracts = serializer.KnownDataContracts;
225 this.isSerializerKnownDataContractsSetExplicit = true;
227 return this.serializerKnownDataContracts;
231 DataContract GetDataContractFromSerializerKnownTypes(XmlQualifiedName qname)
233 DataContractDictionary serializerKnownDataContracts = this.SerializerKnownDataContracts;
234 if (serializerKnownDataContracts == null)
236 DataContract outDataContract;
237 return serializerKnownDataContracts.TryGetValue(qname, out outDataContract) ? outDataContract : null;
240 internal static DataContractDictionary GetDataContractsForKnownTypes(IList<Type> knownTypeList)
242 if (knownTypeList == null) return null;
243 DataContractDictionary dataContracts = new DataContractDictionary();
244 Dictionary<Type, Type> typesChecked = new Dictionary<Type, Type>();
245 for (int i = 0; i < knownTypeList.Count; i++)
247 Type knownType = knownTypeList[i];
248 if (knownType == null)
249 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.NullKnownType, "knownTypes")));
251 DataContract.CheckAndAdd(knownType, typesChecked, ref dataContracts);
253 return dataContracts;
256 internal bool IsKnownType(DataContract dataContract, DataContractDictionary knownDataContracts, Type declaredType)
258 bool knownTypesAddedInCurrentScope = false;
259 if (knownDataContracts != null)
261 scopedKnownTypes.Push(knownDataContracts);
262 knownTypesAddedInCurrentScope = true;
265 bool isKnownType = IsKnownType(dataContract, declaredType);
267 if (knownTypesAddedInCurrentScope)
269 scopedKnownTypes.Pop();
274 internal bool IsKnownType(DataContract dataContract, Type declaredType)
276 DataContract knownContract = ResolveDataContractFromKnownTypes(dataContract.StableName.Name, dataContract.StableName.Namespace, null /*memberTypeContract*/, declaredType);
277 return knownContract != null && knownContract.UnderlyingType == dataContract.UnderlyingType;
280 DataContract ResolveDataContractFromKnownTypes(XmlQualifiedName typeName)
282 DataContract dataContract = PrimitiveDataContract.GetPrimitiveDataContract(typeName.Name, typeName.Namespace);
283 if (dataContract == null)
285 dataContract = scopedKnownTypes.GetDataContract(typeName);
286 if (dataContract == null)
288 dataContract = GetDataContractFromSerializerKnownTypes(typeName);
294 DataContract ResolveDataContractFromDataContractResolver(XmlQualifiedName typeName, Type declaredType)
296 if (TD.DCResolverResolveIsEnabled())
298 TD.DCResolverResolve(typeName.Name + ":" + typeName.Namespace);
301 Type dataContractType = DataContractResolver.ResolveName(typeName.Name, typeName.Namespace, declaredType, KnownTypeResolver);
302 if (dataContractType == null)
308 return GetDataContract(dataContractType);
312 internal Type ResolveNameFromKnownTypes(XmlQualifiedName typeName)
314 DataContract dataContract = ResolveDataContractFromKnownTypes(typeName);
315 if (dataContract == null)
321 return dataContract.OriginalUnderlyingType;
325 protected DataContract ResolveDataContractFromKnownTypes(string typeName, string typeNs, DataContract memberTypeContract, Type declaredType)
327 XmlQualifiedName qname = new XmlQualifiedName(typeName, typeNs);
328 DataContract dataContract;
329 if (DataContractResolver == null)
331 dataContract = ResolveDataContractFromKnownTypes(qname);
335 dataContract = ResolveDataContractFromDataContractResolver(qname, declaredType);
337 if (dataContract == null)
339 if (memberTypeContract != null
340 && !memberTypeContract.UnderlyingType.IsInterface
341 && memberTypeContract.StableName == qname)
343 dataContract = memberTypeContract;
345 if (dataContract == null && rootTypeDataContract != null)
347 dataContract = ResolveDataContractFromRootDataContract(qname);
353 protected virtual DataContract ResolveDataContractFromRootDataContract(XmlQualifiedName typeQName)
355 if (rootTypeDataContract.StableName == typeQName)
356 return rootTypeDataContract;
358 CollectionDataContract collectionContract = rootTypeDataContract as CollectionDataContract;
359 while (collectionContract != null)
361 DataContract itemContract = GetDataContract(GetSurrogatedType(collectionContract.ItemType));
362 if (itemContract.StableName == typeQName)
366 collectionContract = itemContract as CollectionDataContract;