XmlDataContract.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / XmlDataContract.cs / 1 / XmlDataContract.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Runtime.Serialization
{ 
    using System;
    //using System.ServiceModel.Channels; 
    using System.Collections.Generic; 
    using System.Security.Permissions;
    using System.Reflection; 
    using System.Threading;
    using System.Xml;
    using DataContractDictionary=System.Collections.Generic.Dictionary;
    using System.Xml.Serialization; 
    using System.Xml.Schema;
    using System.Security; 
 
    internal delegate IXmlSerializable CreateXmlSerializableDelegate();
    internal sealed class XmlDataContract : DataContract 
    {
        /// 
        /// Critical - holds instance of CriticalHelper which keeps state that is cached statically for serialization.
        ///            Static fields are marked SecurityCritical or readonly to prevent 
        ///            data from being modified or leaked to other components in appdomain.
        ///  
        [SecurityCritical] 
        XmlDataContractCriticalHelper helper;
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal XmlDataContract() : base(new XmlDataContractCriticalHelper()) 
        { 
            helper = base.Helper as XmlDataContractCriticalHelper;
        } 

        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal XmlDataContract(Type type) : base(new XmlDataContractCriticalHelper(type)) 
        {
            helper = base.Helper as XmlDataContractCriticalHelper; 
        }

        internal override DataContractDictionary KnownDataContracts
        { 
            /// 
            /// Critical - fetches the critical KnownDataContracts property 
            /// Safe - KnownDataContracts only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.KnownDataContracts; }
            /// 
            /// Critical - sets the critical KnownDataContracts property
            ///  
            [SecurityCritical]
            set { helper.KnownDataContracts = value; } 
        } 

        internal XmlSchemaType XsdType 
        {
            /// 
            /// Critical - fetches the critical XsdType property
            /// Safe - XsdType only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.XsdType; } 
            /// 
            /// Critical - sets the critical XsdType property 
            /// 
            [SecurityCritical]
            set { helper.XsdType = value; }
        } 

        internal bool IsAnonymous 
        { 
            /// 
            /// Critical - fetches the critical IsAnonymous property 
            /// Safe - IsAnonymous only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.IsAnonymous; } 
        }
 
        internal override bool HasRoot 
        {
            ///  
            /// Critical - fetches the critical HasRoot property
            /// Safe - HasRoot only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.HasRoot; }
            ///  
            /// Critical - sets the critical HasRoot property 
            /// 
            [SecurityCritical] 
            set { helper.HasRoot = value; }
        }

        internal override XmlDictionaryString TopLevelElementName 
        {
            ///  
            /// Critical - fetches the critical TopLevelElementName property 
            /// Safe - TopLevelElementName only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.TopLevelElementName; }
            /// 
            /// Critical - sets the critical TopLevelElementName property 
            /// 
            [SecurityCritical] 
            set { helper.TopLevelElementName = value; } 
        }
 
        internal override XmlDictionaryString TopLevelElementNamespace
        {
            /// 
            /// Critical - fetches the critical TopLevelElementNamespace property 
            /// Safe - TopLevelElementNamespace only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.TopLevelElementNamespace; }
            ///  
            /// Critical - sets the critical TopLevelElementNamespace property
            /// 
            [SecurityCritical]
            set { helper.TopLevelElementNamespace = value; } 
        }
 
        internal bool IsTopLevelElementNullable 
        {
            ///  
            /// Critical - fetches the critical IsTopLevelElementNullable property
            /// Safe - isISerializable only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.IsTopLevelElementNullable; }
            ///  
            /// Critical - sets the critical IsTopLevelElementNullable property 
            /// 
            [SecurityCritical] 
            set { helper.IsTopLevelElementNullable = value; }
        }

        internal bool IsTypeDefinedOnImport 
        {
            ///  
            /// Critical - fetches the critical IsTypeDefinedOnImport property 
            /// Safe - IsTypeDefinedOnImport only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.IsTypeDefinedOnImport; }
            /// 
            /// Critical - sets the critical IsTypeDefinedOnImport property 
            /// 
            [SecurityCritical] 
            set { helper.IsTypeDefinedOnImport = value; } 
        }
 
        internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate
        {
            /// 
            /// Critical - fetches the critical CreateXmlSerializableDelegate property 
            /// Safe - CreateXmlSerializableDelegate only needs to be protected for write; initialized in getter if null
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (helper.CreateXmlSerializableDelegate == null)
                {
                    lock (this)
                    { 
                        if (helper.CreateXmlSerializableDelegate == null)
                        { 
                            CreateXmlSerializableDelegate tempCreateXmlSerializable = GenerateCreateXmlSerializableDelegate(); 
                            Thread.MemoryBarrier();
                            helper.CreateXmlSerializableDelegate = tempCreateXmlSerializable; 
                        }
                    }
                }
                return helper.CreateXmlSerializableDelegate; 
            }
        } 
 
        internal override bool CanContainReferences
        { 
            get { return false; }
        }

        internal override bool IsBuiltInDataContract 
        {
            get 
            { 
                return UnderlyingType == Globals.TypeOfXmlElement || UnderlyingType == Globals.TypeOfXmlNodeArray;
            } 
        }

        /// 
        /// Critical - holds all state used for for (de)serializing XML types. 
        ///            since the data is cached statically, we lock down access to it.
        ///  
        [SecurityCritical(SecurityCriticalScope.Everything)] 
        class XmlDataContractCriticalHelper : DataContract.DataContractCriticalHelper
        { 
            DataContractDictionary knownDataContracts;
            bool isKnownTypeAttributeChecked;
            XmlDictionaryString topLevelElementName;
            XmlDictionaryString topLevelElementNamespace; 
            bool isTopLevelElementNullable;
            bool isTypeDefinedOnImport; 
            XmlSchemaType xsdType; 
            bool hasRoot;
            CreateXmlSerializableDelegate createXmlSerializable; 

            internal XmlDataContractCriticalHelper()
            {
            } 

            internal XmlDataContractCriticalHelper(Type type) : base(type) 
            { 
                if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableCannotHaveDataContract, DataContract.GetClrTypeFullName(type)))); 
                if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableCannotHaveCollectionDataContract, DataContract.GetClrTypeFullName(type))));
                XmlSchemaType xsdType;
                bool hasRoot; 
                XmlQualifiedName stableName;
                SchemaExporter.GetXmlTypeInfo(type, out stableName, out xsdType, out hasRoot); 
                this.StableName = stableName; 
                this.XsdType = xsdType;
                this.HasRoot = hasRoot; 
                XmlDictionary dictionary = new XmlDictionary();
                this.Name = dictionary.Add(StableName.Name);
                this.Namespace = dictionary.Add(StableName.Namespace);
                object[] xmlRootAttributes = (UnderlyingType == null) ? null : UnderlyingType.GetCustomAttributes(Globals.TypeOfXmlRootAttribute, false); 
                if (xmlRootAttributes == null || xmlRootAttributes.Length == 0)
                { 
                    if (hasRoot) 
                    {
                        topLevelElementName = Name; 
                        topLevelElementNamespace = (this.StableName.Namespace == Globals.SchemaNamespace) ? DictionaryGlobals.EmptyString : Namespace;
                        isTopLevelElementNullable = true;
                    }
                } 
                else
                { 
                    if (hasRoot) 
                    {
                        XmlRootAttribute xmlRootAttribute = (XmlRootAttribute)xmlRootAttributes[0]; 
                        isTopLevelElementNullable = xmlRootAttribute.IsNullable;
                        string elementName = xmlRootAttribute.ElementName;
                        topLevelElementName = (elementName == null || elementName.Length == 0) ? Name : dictionary.Add(DataContract.EncodeLocalName(elementName));
                        string elementNs = xmlRootAttribute.Namespace; 
                        topLevelElementNamespace = (elementNs == null || elementNs.Length == 0) ? DictionaryGlobals.EmptyString : dictionary.Add(elementNs);
                    } 
                    else 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IsAnyCannotHaveXmlRoot, DataContract.GetClrTypeFullName(UnderlyingType)))); 
                    }
                }
            }
 
            internal override DataContractDictionary KnownDataContracts
            { 
                get 
                {
                    if (!isKnownTypeAttributeChecked && UnderlyingType != null) 
                    {
                        lock (this)
                        {
                            if (!isKnownTypeAttributeChecked) 
                            {
                                knownDataContracts = DataContract.ImportKnownTypeAttributes(this.UnderlyingType); 
                                Thread.MemoryBarrier(); 
                                isKnownTypeAttributeChecked = true;
                            } 
                        }
                    }
                    return knownDataContracts;
                } 
                set { knownDataContracts = value; }
            } 
 
            internal XmlSchemaType XsdType
            { 
                get { return xsdType; }
                set { xsdType = value; }
            }
 
            internal bool IsAnonymous
            { 
                get { return xsdType != null; } 
            }
 
            internal override bool HasRoot
            {
                get { return hasRoot; }
                set { hasRoot = value; } 
            }
 
            internal override XmlDictionaryString TopLevelElementName 
            {
                get { return topLevelElementName; } 
                set { topLevelElementName = value; }
            }

            internal override XmlDictionaryString TopLevelElementNamespace 
            {
                get { return topLevelElementNamespace; } 
                set { topLevelElementNamespace = value; } 
            }
 
            internal bool IsTopLevelElementNullable
            {
                get { return isTopLevelElementNullable; }
                set { isTopLevelElementNullable = value; } 
            }
 
            internal bool IsTypeDefinedOnImport 
            {
                get { return isTypeDefinedOnImport; } 
                set { isTypeDefinedOnImport = value; }
            }

            internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate 
            {
                get { return createXmlSerializable; } 
                set { createXmlSerializable = value; } 
            }
 
        }

        ConstructorInfo GetConstructor()
        { 
            Type type = UnderlyingType;
 
            if (type.IsValueType) 
                return null;
 
            ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
            if (ctor == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));
 
            return ctor;
        } 
 
        /// 
        /// Critical - sets critical properties on XmlDataContract 
        /// 
        [SecurityCritical]
        internal void SetTopLevelElementName(XmlQualifiedName elementName)
        { 
            if (elementName != null)
            { 
                XmlDictionary dictionary = new XmlDictionary(); 
                this.TopLevelElementName = dictionary.Add(elementName.Name);
                this.TopLevelElementNamespace = dictionary.Add(elementName.Namespace); 
            }
        }

        ///  
        /// Critical - calls CodeGenerator.BeginMethod which is SecurityCritical
        /// Safe - self-contained: returns the delegate to the generated IL but otherwise all IL generation is self-contained here 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate() 
        {
            Type type = this.UnderlyingType;
            CodeGenerator ilg = new CodeGenerator();
            bool memberAccessFlag = RequiresMemberAccessForCreate(null); 
            try
            { 
                ilg.BeginMethod("Create" + DataContract.GetClrTypeFullName(type), typeof(CreateXmlSerializableDelegate), memberAccessFlag); 
            }
            catch (SecurityException securityException) 
            {
                if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
                {
                    RequiresMemberAccessForCreate(securityException); 
                }
                else 
                { 
                    throw;
                } 
            }
            if (type.IsValueType)
            {
                System.Reflection.Emit.LocalBuilder local = ilg.DeclareLocal(type, type.Name + "Value"); 
                ilg.Ldloca(local);
                ilg.InitObj(type); 
                ilg.Ldloc(local); 
            }
            else 
            {
                ilg.New(GetConstructor());
            }
            ilg.ConvertValue(this.UnderlyingType, Globals.TypeOfIXmlSerializable); 
            ilg.Ret();
            return (CreateXmlSerializableDelegate)ilg.EndMethod(); 
        } 

        ///  
        /// Review - calculates whether this Xml type requires MemberAccessPermission for deserialization.
        ///          since this information is used to determine whether to give the generated code access
        ///          permissions to private members, any changes to the logic should be reviewed.
        ///  
        [SecurityRequiresReview]
        bool RequiresMemberAccessForCreate(SecurityException securityException) 
        { 
            if (!IsTypeVisible(UnderlyingType))
            { 
                if (securityException != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(SR.PartialTrustIXmlSerializableTypeNotPublic, DataContract.GetClrTypeFullName(UnderlyingType)), 
                        securityException));
                } 
                return true; 
            }
 
            if (ConstructorRequiresMemberAccess(GetConstructor()))
            {
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(SR.PartialTrustIXmlSerialzableNoPublicConstructor, DataContract.GetClrTypeFullName(UnderlyingType)), 
                        securityException)); 
                }
                return true; 
            }

            return false;
        } 

        internal override bool Equals(object other, Dictionary checkedContracts) 
        { 
            if (IsEqualOrChecked(other, checkedContracts))
                return true; 

            XmlDataContract dataContract = other as XmlDataContract;
            if (dataContract != null)
            { 
                if (this.HasRoot != dataContract.HasRoot)
                    return false; 
 
                if (this.IsAnonymous)
                { 
                    return dataContract.IsAnonymous;
                }
                else
                { 
                    return (StableName.Name == dataContract.StableName.Name && StableName.Namespace == dataContract.StableName.Namespace);
                } 
            } 
            return false;
        } 

        public override int GetHashCode()
        {
            return base.GetHashCode(); 
        }
 
        public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context) 
        {
            if (context == null) 
                XmlObjectSerializerWriteContext.WriteRootIXmlSerializable(xmlWriter, obj);
            else
                context.WriteIXmlSerializable(xmlWriter, obj);
        } 

        public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context) 
        { 
            object o;
            if (context == null) 
            {
                o = XmlObjectSerializerReadContext.ReadRootIXmlSerializable(xmlReader, this, true /*isMemberType*/);
            }
            else 
            {
                o = context.ReadIXmlSerializable(xmlReader, this, true /*isMemberType*/); 
                context.AddNewObject(o); 
            }
            xmlReader.ReadEndElement(); 
            return o;
        }

    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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