XmlObjectSerializerReadContextComplex.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / XmlObjectSerializerReadContextComplex.cs / 1305376 / XmlObjectSerializerReadContextComplex.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Collections; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Xml; 
    using DataContractDictionary = System.Collections.Generic.Dictionary;
    using System.Collections.Generic; 
    using System.Runtime.Serialization.Formatters; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Runtime.CompilerServices;

#if USE_REFEMIT
    public class XmlObjectSerializerReadContextComplex : XmlObjectSerializerReadContext 
#else
    internal class XmlObjectSerializerReadContextComplex : XmlObjectSerializerReadContext 
#endif 
    {
        static Hashtable dataContractTypeCache = new Hashtable(); 

        bool preserveObjectReferences;
        protected IDataContractSurrogate dataContractSurrogate;
        SerializationMode mode; 
        SerializationBinder binder;
        ISurrogateSelector surrogateSelector; 
        FormatterAssemblyStyle assemblyFormat; 
        Hashtable surrogateDataContracts;
 
        internal XmlObjectSerializerReadContextComplex(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
            : base(serializer, rootTypeDataContract, dataContractResolver)
        {
            this.mode = SerializationMode.SharedContract; 
            this.preserveObjectReferences = serializer.PreserveObjectReferences;
            this.dataContractSurrogate = serializer.DataContractSurrogate; 
        } 

        internal XmlObjectSerializerReadContextComplex(NetDataContractSerializer serializer) 
            : base(serializer)
        {
            this.mode = SerializationMode.SharedType;
            this.preserveObjectReferences = true; 
            this.binder = serializer.Binder;
            this.surrogateSelector = serializer.SurrogateSelector; 
            this.assemblyFormat = serializer.AssemblyFormat; 
        }
 
        internal XmlObjectSerializerReadContextComplex(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
            : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
        {
        } 

        internal override SerializationMode Mode 
        { 
            get { return mode; }
        } 

        internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
        {
            DataContract dataContract = null; 
            if (mode == SerializationMode.SharedType && surrogateSelector != null)
            { 
                dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, null /*type*/, ref surrogateDataContracts); 
            }
 
            if (dataContract != null)
            {
                if (this.IsGetOnlyCollection && dataContract is SurrogateDataContract)
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
                        DataContract.GetClrTypeFullName(dataContract.UnderlyingType)))); 
                } 
                return dataContract;
            } 

            return base.GetDataContract(id, typeHandle);
        }
 
        internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
        { 
            DataContract dataContract = null; 
            if (mode == SerializationMode.SharedType && surrogateSelector != null)
            { 
                dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, type, ref surrogateDataContracts);
            }

            if (dataContract != null) 
            {
                if (this.IsGetOnlyCollection && dataContract is SurrogateDataContract) 
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
                        DataContract.GetClrTypeFullName(dataContract.UnderlyingType)))); 
                }
                return dataContract;
            }
 
            return base.GetDataContract(typeHandle, type);
        } 
 
        public override object InternalDeserialize(XmlReaderDelegator xmlReader, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, string name, string ns)
        { 
            if (mode == SerializationMode.SharedContract)
            {
                if (dataContractSurrogate == null)
                    return base.InternalDeserialize(xmlReader, declaredTypeID, declaredTypeHandle, name, ns); 
                else
                    return InternalDeserializeWithSurrogate(xmlReader, Type.GetTypeFromHandle(declaredTypeHandle), null /*surrogateDataContract*/, name, ns); 
            } 
            else
            { 
                return InternalDeserializeInSharedTypeMode(xmlReader, declaredTypeID, Type.GetTypeFromHandle(declaredTypeHandle), name, ns);
            }
        }
 
        internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, string name, string ns)
        { 
            if (mode == SerializationMode.SharedContract) 
            {
                if (dataContractSurrogate == null) 
                    return base.InternalDeserialize(xmlReader, declaredType, name, ns);
                else
                    return InternalDeserializeWithSurrogate(xmlReader, declaredType, null /*surrogateDataContract*/, name, ns);
            } 
            else
            { 
                return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns); 
            }
        } 

        internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, string name, string ns)
        {
            if (mode == SerializationMode.SharedContract) 
            {
                if (dataContractSurrogate == null) 
                    return base.InternalDeserialize(xmlReader, declaredType, dataContract, name, ns); 
                else
                    return InternalDeserializeWithSurrogate(xmlReader, declaredType, dataContract, name, ns); 
            }
            else
            {
                return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns); 
            }
        } 
 
        object InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader, int declaredTypeID, Type declaredType, string name, string ns)
        { 
            object retObj = null;
            if (TryHandleNullOrRef(xmlReader, declaredType, name, ns, ref retObj))
                return retObj;
 
            DataContract dataContract;
            string assemblyName = attributes.ClrAssembly; 
            string typeName = attributes.ClrType; 
            if (assemblyName != null && typeName != null)
            { 
                Assembly assembly;
                Type type;
                dataContract = ResolveDataContractInSharedTypeMode(assemblyName, typeName, out assembly, out type);
                if (dataContract == null) 
                {
                    if (assembly == null) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.AssemblyNotFound, assemblyName))); 
                    if (type == null)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ClrTypeNotFound, assembly.FullName, typeName))); 
                }
                //Array covariance is not supported in XSD. If declared type is array, data is sent in format of base array
                if (declaredType != null && declaredType.IsArray)
                    dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle); 
            }
            else 
            { 
                if (assemblyName != null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName)))); 
                else if (typeName != null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrAssemblyLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
                else if (declaredType == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName)))); 
                dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle);
            } 
            return ReadDataContractValue(dataContract, xmlReader); 
        }
 
        object InternalDeserializeWithSurrogate(XmlReaderDelegator xmlReader, Type declaredType, DataContract surrogateDataContract, string name, string ns)
        {
            DataContract dataContract = surrogateDataContract ??
                GetDataContract(DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, declaredType)); 
            if (this.IsGetOnlyCollection && dataContract.UnderlyingType != declaredType)
            { 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser, 
                    DataContract.GetClrTypeFullName(declaredType))));
            } 
            ReadAttributes(xmlReader);
            string objectId = GetObjectId();
            object oldObj = InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract);
            object obj = DataContractSurrogateCaller.GetDeserializedObject(dataContractSurrogate, oldObj, dataContract.UnderlyingType, declaredType); 
            ReplaceDeserializedObject(objectId, oldObj, obj);
            return obj; 
        } 

        Type ResolveDataContractTypeInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly) 
        {
            assembly = null;
            Type type = null;
 
            if (binder != null)
                type = binder.BindToType(assemblyName, typeName); 
            if (type == null) 
            {
                XmlObjectDataContractTypeKey key = new XmlObjectDataContractTypeKey(assemblyName, typeName); 
                XmlObjectDataContractTypeInfo dataContractTypeInfo = (XmlObjectDataContractTypeInfo)dataContractTypeCache[key];
                if (dataContractTypeInfo == null)
                {
                    if (assemblyFormat == FormatterAssemblyStyle.Full) 
                    {
                        if (assemblyName == Globals.MscorlibAssemblyName) 
                        { 
                            assembly = Globals.TypeOfInt.Assembly;
                        } 
                        else
                        {
                            assembly = Assembly.Load(assemblyName);
                        } 
                        if (assembly != null)
                            type = assembly.GetType(typeName); 
                    } 
                    else
                    { 
                        assembly = XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName(assemblyName);
                        if (assembly != null)
                        {
                            // Catching any exceptions that could be thrown from a failure on assembly load 
                            // This is necessary, for example, if there are generic parameters that are qualified with a version of the assembly that predates the one available
                            try 
                            { 
                                type = assembly.GetType(typeName);
                            } 
                            catch (TypeLoadException) { }
                            catch (FileNotFoundException) { }
                            catch (FileLoadException) { }
                            catch (BadImageFormatException) { } 

                            if (type == null) 
                            { 
                                type = Type.GetType(typeName, XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName, new TopLevelAssemblyTypeResolver(assembly).ResolveType, false /* throwOnError */);
                            } 
                        }
                    }

                    if (type != null) 
                    {
                        dataContractTypeInfo = new XmlObjectDataContractTypeInfo(assembly, type); 
                        lock (dataContractTypeCache) 
                        {
                            if (!dataContractTypeCache.ContainsKey(key)) 
                            {
                                dataContractTypeCache[key] = dataContractTypeInfo;
                            }
                        } 
                    }
                } 
                else 
                {
                    assembly = dataContractTypeInfo.Assembly; 
                    type = dataContractTypeInfo.Type;
                }
            }
 
            return type;
        } 
 
        DataContract ResolveDataContractInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly, out Type type)
        { 
            type = ResolveDataContractTypeInSharedTypeMode(assemblyName, typeName, out assembly);
            if (type != null)
            {
                return GetDataContract(type); 
            }
 
            return null; 
        }
 
        protected override DataContract ResolveDataContractFromTypeName()
        {
            if (mode == SerializationMode.SharedContract)
            { 
                return base.ResolveDataContractFromTypeName();
            } 
            else 
            {
                if (attributes.ClrAssembly != null && attributes.ClrType != null) 
                {
                    Assembly assembly;
                    Type type;
                    return ResolveDataContractInSharedTypeMode(attributes.ClrAssembly, attributes.ClrType, out assembly, out type); 
                }
            } 
            return null; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISurrogateSelector", Safe = "Demands for FullTrust")]
        [SecuritySafeCritical]
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        [MethodImpl(MethodImplOptions.NoInlining)] 
        bool CheckIfTypeSerializableForSharedTypeMode(Type memberType)
        { 
            Fx.Assert(surrogateSelector != null, "Method should not be called when surrogateSelector is null."); 
            ISurrogateSelector surrogateSelectorNotUsed;
            return (surrogateSelector.GetSurrogate(memberType, GetStreamingContext(), out surrogateSelectorNotUsed) != null); 
        }

        internal override void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
        { 
            if (mode == SerializationMode.SharedType && surrogateSelector != null &&
                CheckIfTypeSerializableForSharedTypeMode(memberType)) 
            { 
                return;
            } 
            else
            {
                if (dataContractSurrogate != null)
                { 
                    while (memberType.IsArray)
                        memberType = memberType.GetElementType(); 
                    memberType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, memberType); 
                    if (!DataContract.IsTypeSerializable(memberType))
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeNotSerializable, memberType))); 
                    return;
                }
            }
 
            base.CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
        } 
 
        internal override Type GetSurrogatedType(Type type)
        { 
            if (dataContractSurrogate == null)
            {
                return base.GetSurrogatedType(type);
            } 
            else
            { 
                type = DataContract.UnwrapNullableType(type); 
                Type surrogateType = DataContractSerializer.GetSurrogatedType(dataContractSurrogate, type);
                if (this.IsGetOnlyCollection && surrogateType != type) 
                {
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
                        DataContract.GetClrTypeFullName(type))));
                } 
                else
                { 
                    return surrogateType; 
                }
            } 
        }

#if USE_REFEMIT
        public override int GetArraySize() 
#else
        internal override int GetArraySize() 
#endif 
        {
            return preserveObjectReferences ? attributes.ArraySZSize : -1; 
        }

        static Assembly ResolveSimpleAssemblyName(AssemblyName assemblyName)
        { 
            return ResolveSimpleAssemblyName(assemblyName.FullName);
        } 
 
        static Assembly ResolveSimpleAssemblyName(string assemblyName)
        { 
            Assembly assembly;
            if (assemblyName == Globals.MscorlibAssemblyName)
            {
                assembly = Globals.TypeOfInt.Assembly; 
            }
            else 
            { 
                assembly = Assembly.LoadWithPartialName(assemblyName);
                if (assembly == null) 
                {
                    AssemblyName an = new AssemblyName(assemblyName);
                    an.Version = null;
                    assembly = Assembly.LoadWithPartialName(an.FullName); 
                }
            } 
            return assembly; 
        }
 
        sealed class TopLevelAssemblyTypeResolver
        {
            Assembly topLevelAssembly;
 
            public TopLevelAssemblyTypeResolver(Assembly topLevelAssembly)
            { 
                this.topLevelAssembly = topLevelAssembly; 
            }
            public Type ResolveType(Assembly assembly, string simpleTypeName, bool ignoreCase) 
            {
                if (assembly == null)
                    assembly = topLevelAssembly;
 
                return assembly.GetType(simpleTypeName, false, ignoreCase);
            } 
        } 

        class XmlObjectDataContractTypeInfo 
        {
            Assembly assembly;
            Type type;
            public XmlObjectDataContractTypeInfo(Assembly assembly, Type type) 
            {
                this.assembly = assembly; 
                this.type = type; 
            }
 
            public Assembly Assembly
            {
                get
                { 
                    return this.assembly;
                } 
            } 

            public Type Type 
            {
                get
                {
                    return this.type; 
                }
            } 
        } 

        class XmlObjectDataContractTypeKey 
        {
            string assemblyName;
            string typeName;
            public XmlObjectDataContractTypeKey(string assemblyName, string typeName) 
            {
                this.assemblyName = assemblyName; 
                this.typeName = typeName; 
            }
 
            public override bool Equals(object obj)
            {
                if (object.ReferenceEquals(this, obj))
                    return true; 

                XmlObjectDataContractTypeKey other = obj as XmlObjectDataContractTypeKey; 
                if (other == null) 
                    return false;
 
                if (this.assemblyName != other.assemblyName)
                    return false;

                if (this.typeName != other.typeName) 
                    return false;
 
                return true; 
            }
 
            public override int GetHashCode()
            {
                int hashCode = 0;
                if (this.assemblyName != null) 
                    hashCode = this.assemblyName.GetHashCode();
 
                if (this.typeName != null) 
                    hashCode ^= this.typeName.GetHashCode();
 
                return hashCode;
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK