DataContractJsonSerializer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

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

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

namespace System.Runtime.Serialization.Json 
{
    using System.Runtime.Serialization; 
    using System; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.ServiceModel; 
    using System.Collections;
    using DataContractDictionary = System.Collections.Generic.Dictionary; 
    using System.Runtime.CompilerServices; 

    [TypeForwardedFrom("System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] 
    public sealed class DataContractJsonSerializer : XmlObjectSerializer
    {
        internal IList knownTypeList;
        internal DataContractDictionary knownDataContracts; 
        bool alwaysEmitTypeInformation;
        IDataContractSurrogate dataContractSurrogate; 
        bool ignoreExtensionDataObject; 
        ReadOnlyCollection knownTypeCollection;
        int maxItemsInObjectGraph; 
        DataContract rootContract; // post-surrogate
        XmlDictionaryString rootName;
        bool rootNameRequiresMapping;
        Type rootType; 

        public DataContractJsonSerializer(Type type) 
            : this(type, (IEnumerable) null) 
        {
        } 

        public DataContractJsonSerializer(Type type, string rootName)
            : this(type, rootName, null)
        { 
        }
 
        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName) 
            : this(type, rootName, null)
        { 
        }

        public DataContractJsonSerializer(Type type, IEnumerable knownTypes)
            : this(type, knownTypes, int.MaxValue, false, null, false) 
        {
        } 
 

        public DataContractJsonSerializer(Type type, string rootName, IEnumerable knownTypes) 
            : this(type, rootName, knownTypes, int.MaxValue, false, null, false)
        {
        }
 
        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName, IEnumerable knownTypes)
            : this(type, rootName, knownTypes, int.MaxValue, false, null, false) 
        { 
        }
 
        public DataContractJsonSerializer(Type type,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        { 
            Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        } 

        public DataContractJsonSerializer(Type type, string rootName,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph, 
            bool ignoreExtensionDataObject,
            IDataContractSurrogate dataContractSurrogate, 
            bool alwaysEmitTypeInformation) 
        {
            XmlDictionary dictionary = new XmlDictionary(2); 
            Initialize(type, dictionary.Add(rootName), knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        }

        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName, 
            IEnumerable knownTypes,
            int maxItemsInObjectGraph, 
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        {
            Initialize(type, rootName, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        }
 
        public IDataContractSurrogate DataContractSurrogate
        { 
            get { return dataContractSurrogate; } 
        }
 
        public bool IgnoreExtensionDataObject
        {
            get { return ignoreExtensionDataObject; }
        } 

        public ReadOnlyCollection KnownTypes 
        { 
            get
            { 
                if (knownTypeCollection == null)
                {
                    if (knownTypeList != null)
                    { 
                        knownTypeCollection = new ReadOnlyCollection(knownTypeList);
                    } 
                    else 
                    {
                        knownTypeCollection = new ReadOnlyCollection(Globals.EmptyTypeArray); 
                    }
                }
                return knownTypeCollection;
            } 
        }
 
        internal override DataContractDictionary KnownDataContracts 
        {
            get 
            {
                if (this.knownDataContracts == null && this.knownTypeList != null)
                {
                    // This assignment may be performed concurrently and thus is a race condition. 
                    // It's safe, however, because at worse a new (and identical) dictionary of
                    // data contracts will be created and re-assigned to this field.  Introduction 
                    // of a lock here could lead to deadlocks. 
                    this.knownDataContracts = XmlObjectSerializerContext.GetDataContractsForKnownTypes(this.knownTypeList);
                } 
                return this.knownDataContracts;
            }
        }
 
        public int MaxItemsInObjectGraph
        { 
            get { return maxItemsInObjectGraph; } 
        }
 
        internal bool AlwaysEmitTypeInformation
        {
            get
            { 
                return alwaysEmitTypeInformation;
            } 
        } 

        DataContract RootContract 
        {
            get
            {
                if (rootContract == null) 
                {
                    rootContract = DataContract.GetDataContract(((dataContractSurrogate == null) ? rootType : 
                        DataContractSerializer.GetSurrogatedType(dataContractSurrogate, rootType))); 
                    CheckIfTypeIsReference(rootContract);
                } 
                return rootContract;
            }
        }
 
        XmlDictionaryString RootName
        { 
            get 
            {
                return rootName ?? JsonGlobals.rootDictionaryString; 
            }
        }

        public override bool IsStartObject(XmlReader reader) 
        {
            return IsStartObjectHandleExceptions(new JsonReaderDelegator(reader)); 
        } 

        public override bool IsStartObject(XmlDictionaryReader reader) 
        {
            return IsStartObjectHandleExceptions(new JsonReaderDelegator(reader));
        }
 
        public override object ReadObject(Stream stream)
        { 
            CheckNull(stream, "stream"); 
            return ReadObject(JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max));
        } 

        public override object ReadObject(XmlReader reader)
        {
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), true); 
        }
 
        public override object ReadObject(XmlReader reader, bool verifyObjectName) 
        {
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), verifyObjectName); 
        }

        public override object ReadObject(XmlDictionaryReader reader)
        { 
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), true); // verifyObjectName
        } 
 
        public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
        { 
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), verifyObjectName);
        }

        public override void WriteEndObject(XmlWriter writer) 
        {
            WriteEndObjectHandleExceptions(new JsonWriterDelegator(writer)); 
        } 

        public override void WriteEndObject(XmlDictionaryWriter writer) 
        {
            WriteEndObjectHandleExceptions(new JsonWriterDelegator(writer));
        }
 

        public override void WriteObject(Stream stream, object graph) 
        { 
            CheckNull(stream, "stream");
            XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false); //  ownsStream 
            WriteObject(jsonWriter, graph);
            jsonWriter.Flush();
        }
 
        public override void WriteObject(XmlWriter writer, object graph)
        { 
            WriteObjectHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }
 
        public override void WriteObject(XmlDictionaryWriter writer, object graph)
        {
            WriteObjectHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 

        public override void WriteObjectContent(XmlWriter writer, object graph) 
        { 
            WriteObjectContentHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 

        public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
        {
            WriteObjectContentHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }
 
        public override void WriteStartObject(XmlWriter writer, object graph) 
        {
            WriteStartObjectHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }

        public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
        { 
            WriteStartObjectHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 
 
        internal static bool CheckIfJsonNameRequiresMapping(string jsonName)
        { 
            if (jsonName != null)
            {
                if (!DataContract.IsValidNCName(jsonName))
                { 
                    return true;
                } 
 
                for (int i = 0; i < jsonName.Length; i++)
                { 
                    if (XmlJsonWriter.CharacterNeedsEscaping(jsonName[i]))
                    {
                        return true;
                    } 
                }
            } 
            return false; 
        }
 
        internal static bool CheckIfJsonNameRequiresMapping(XmlDictionaryString jsonName)
        {
            return (jsonName == null) ? false : CheckIfJsonNameRequiresMapping(jsonName.Value);
        } 

        internal static bool CheckIfXmlNameRequiresMapping(string xmlName) 
        { 
            return (xmlName == null) ? false : CheckIfJsonNameRequiresMapping(ConvertXmlNameToJsonName(xmlName));
        } 

        internal static bool CheckIfXmlNameRequiresMapping(XmlDictionaryString xmlName)
        {
            return (xmlName == null) ? false : CheckIfXmlNameRequiresMapping(xmlName.Value); 
        }
 
        internal static string ConvertXmlNameToJsonName(string xmlName) 
        {
            return XmlConvert.DecodeName(xmlName); 
        }

        internal static XmlDictionaryString ConvertXmlNameToJsonName(XmlDictionaryString xmlName)
        { 
            return (xmlName == null) ? null : new XmlDictionary().Add(ConvertXmlNameToJsonName(xmlName.Value));
        } 
 
        internal static bool IsJsonLocalName(XmlReaderDelegator reader, string elementName)
        { 
            string name;
            if (XmlObjectSerializerReadContextComplexJson.TryGetJsonLocalName(reader, out name))
            {
                return (elementName == name); 
            }
            return false; 
        } 

        internal static object ReadJsonValue(DataContract contract, XmlReaderDelegator reader, XmlObjectSerializerReadContextComplexJson context) 
        {
            return JsonDataContract.GetJsonDataContract(contract).ReadJsonValue(reader, context);
        }
 
        internal static void WriteJsonNull(XmlWriterDelegator writer)
        { 
            writer.WriteAttributeString(null, JsonGlobals.typeString, null, JsonGlobals.nullString); //  prefix //  namespace 
        }
 
        internal static void WriteJsonValue(JsonDataContract contract, XmlWriterDelegator writer, object graph, XmlObjectSerializerWriteContextComplexJson context, RuntimeTypeHandle declaredTypeHandle)
        {
            contract.WriteJsonValue(writer, graph, context, declaredTypeHandle);
        } 

        internal override Type GetDeserializeType() 
        { 
            return rootType;
        } 

        internal override Type GetSerializeType(object graph)
        {
            return (graph == null) ? rootType : graph.GetType(); 
        }
 
        internal override bool InternalIsStartObject(XmlReaderDelegator reader) 
        {
            if (IsRootElement(reader, RootContract, RootName, XmlDictionaryString.Empty)) 
            {
                return true;
            }
 
            return IsJsonLocalName(reader, RootName.Value);
        } 
 
        internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName)
        { 
            if (MaxItemsInObjectGraph == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
            } 

            if (verifyObjectName) 
            { 
                if (!InternalIsStartObject(xmlReader))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExpectingElement, XmlDictionaryString.Empty, RootName), xmlReader));
                }
            }
            else if (!IsStartElement(xmlReader)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExpectingElementAtDeserialize, XmlNodeType.Element), xmlReader)); 
            } 

            DataContract contract = RootContract; 
            if (contract.IsPrimitive && object.ReferenceEquals(contract.UnderlyingType, rootType))// handle Nullable differently
            {
                return DataContractJsonSerializer.ReadJsonValue(contract, xmlReader, null);
            } 

            XmlObjectSerializerReadContextComplexJson context = XmlObjectSerializerReadContextComplexJson.CreateContext(this, contract); 
            return context.InternalDeserialize(xmlReader, rootType, contract, null, null); 
        }
 
        internal override void InternalWriteEndObject(XmlWriterDelegator writer)
        {
            writer.WriteEndElement();
        } 

        internal override void InternalWriteObject(XmlWriterDelegator writer, object graph) 
        { 
            InternalWriteStartObject(writer, graph);
            InternalWriteObjectContent(writer, graph); 
            InternalWriteEndObject(writer);
        }

        internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph) 
        {
            if (MaxItemsInObjectGraph == 0) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
            } 

            DataContract contract = RootContract;
            Type declaredType = contract.UnderlyingType;
            Type graphType = (graph == null) ? declaredType : graph.GetType(); 

            if (dataContractSurrogate != null) 
            { 
                graph = DataContractSerializer.SurrogateToDataContractType(dataContractSurrogate, graph, declaredType, ref graphType);
            } 

            if (graph == null)
            {
                WriteJsonNull(writer); 
            }
            else 
            { 
                if (declaredType == graphType)
                { 
                    if (contract.CanContainReferences)
                    {
                        XmlObjectSerializerWriteContextComplexJson context = XmlObjectSerializerWriteContextComplexJson.CreateContext(this, contract);
                        context.OnHandleReference(writer, graph, true); //  canContainReferences 
                        context.SerializeWithoutXsiType(contract, writer, graph, declaredType.TypeHandle);
                    } 
                    else 
                    {
                        DataContractJsonSerializer.WriteJsonValue(JsonDataContract.GetJsonDataContract(contract), writer, graph, null, declaredType.TypeHandle); //  XmlObjectSerializerWriteContextComplexJson 
                    }
                }
                else
                { 
                    XmlObjectSerializerWriteContextComplexJson context = XmlObjectSerializerWriteContextComplexJson.CreateContext(this, RootContract);
                    contract = DataContractJsonSerializer.GetDataContract(contract, declaredType, graphType); 
                    if (contract.CanContainReferences) 
                    {
                        context.OnHandleReference(writer, graph, true); //  canContainCyclicReference 
                        context.SerializeWithXsiTypeAtTopLevel(contract, writer, graph, declaredType.TypeHandle, graphType);
                    }
                    else
                    { 
                        context.SerializeWithoutXsiType(contract, writer, graph, declaredType.TypeHandle);
                    } 
                } 
            }
        } 

        internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
        {
            if (this.rootNameRequiresMapping) 
            {
                writer.WriteStartElement("a", JsonGlobals.itemString, JsonGlobals.itemString); 
                writer.WriteAttributeString(null, JsonGlobals.itemString, null, RootName.Value); 
            }
            else 
            {
                writer.WriteStartElement(RootName, XmlDictionaryString.Empty);
            }
        } 

        void AddCollectionItemTypeToKnownTypes(Type knownType) 
        { 
            Type itemType;
            Type typeToCheck = knownType; 
            while (CollectionDataContract.IsCollection(typeToCheck, out itemType))
            {
                if (itemType.IsGenericType && (itemType.GetGenericTypeDefinition() == Globals.TypeOfKeyValue))
                { 
                    itemType = Globals.TypeOfKeyValuePair.MakeGenericType(itemType.GetGenericArguments());
                } 
                this.knownTypeList.Add(itemType); 
                typeToCheck = itemType;
            } 
        }

        void Initialize(Type type,
            IEnumerable knownTypes, 
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate, 
            bool alwaysEmitTypeInformation)
        { 
            CheckNull(type, "type");
            this.rootType = type;

            if (knownTypes != null) 
            {
                this.knownTypeList = new List(); 
                foreach (Type knownType in knownTypes) 
                {
                    this.knownTypeList.Add(knownType); 
                    if (knownType != null)
                    {
                        AddCollectionItemTypeToKnownTypes(knownType);
                    } 
                }
            } 
 
            if (maxItemsInObjectGraph < 0)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxItemsInObjectGraph", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
            }
            this.maxItemsInObjectGraph = maxItemsInObjectGraph;
            this.ignoreExtensionDataObject = ignoreExtensionDataObject; 
            this.dataContractSurrogate = dataContractSurrogate;
            this.alwaysEmitTypeInformation = alwaysEmitTypeInformation; 
        } 

        void Initialize(Type type, 
            XmlDictionaryString rootName,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        { 
            Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
            this.rootName = ConvertXmlNameToJsonName(rootName); 
            this.rootNameRequiresMapping = CheckIfJsonNameRequiresMapping(this.rootName);
        }

        internal static void CheckIfTypeIsReference(DataContract dataContract) 
        {
            if (dataContract.IsReference) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    XmlObjectSerializer.CreateSerializationException(SR.GetString( 
                        SR.JsonUnsupportedForIsReference,
                        DataContract.GetClrTypeFullName(dataContract.UnderlyingType),
                        dataContract.IsReference)));
            } 
        }
 
        internal static DataContract GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType) 
        {
            DataContract contract = DataContractSerializer.GetDataContract(declaredTypeContract, declaredType, objectType); 
            CheckIfTypeIsReference(contract);
            return contract;
        }
    } 
}

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

namespace System.Runtime.Serialization.Json 
{
    using System.Runtime.Serialization; 
    using System; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.ServiceModel; 
    using System.Collections;
    using DataContractDictionary = System.Collections.Generic.Dictionary; 
    using System.Runtime.CompilerServices; 

    [TypeForwardedFrom("System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] 
    public sealed class DataContractJsonSerializer : XmlObjectSerializer
    {
        internal IList knownTypeList;
        internal DataContractDictionary knownDataContracts; 
        bool alwaysEmitTypeInformation;
        IDataContractSurrogate dataContractSurrogate; 
        bool ignoreExtensionDataObject; 
        ReadOnlyCollection knownTypeCollection;
        int maxItemsInObjectGraph; 
        DataContract rootContract; // post-surrogate
        XmlDictionaryString rootName;
        bool rootNameRequiresMapping;
        Type rootType; 

        public DataContractJsonSerializer(Type type) 
            : this(type, (IEnumerable) null) 
        {
        } 

        public DataContractJsonSerializer(Type type, string rootName)
            : this(type, rootName, null)
        { 
        }
 
        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName) 
            : this(type, rootName, null)
        { 
        }

        public DataContractJsonSerializer(Type type, IEnumerable knownTypes)
            : this(type, knownTypes, int.MaxValue, false, null, false) 
        {
        } 
 

        public DataContractJsonSerializer(Type type, string rootName, IEnumerable knownTypes) 
            : this(type, rootName, knownTypes, int.MaxValue, false, null, false)
        {
        }
 
        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName, IEnumerable knownTypes)
            : this(type, rootName, knownTypes, int.MaxValue, false, null, false) 
        { 
        }
 
        public DataContractJsonSerializer(Type type,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        { 
            Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        } 

        public DataContractJsonSerializer(Type type, string rootName,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph, 
            bool ignoreExtensionDataObject,
            IDataContractSurrogate dataContractSurrogate, 
            bool alwaysEmitTypeInformation) 
        {
            XmlDictionary dictionary = new XmlDictionary(2); 
            Initialize(type, dictionary.Add(rootName), knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        }

        public DataContractJsonSerializer(Type type, XmlDictionaryString rootName, 
            IEnumerable knownTypes,
            int maxItemsInObjectGraph, 
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        {
            Initialize(type, rootName, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
        }
 
        public IDataContractSurrogate DataContractSurrogate
        { 
            get { return dataContractSurrogate; } 
        }
 
        public bool IgnoreExtensionDataObject
        {
            get { return ignoreExtensionDataObject; }
        } 

        public ReadOnlyCollection KnownTypes 
        { 
            get
            { 
                if (knownTypeCollection == null)
                {
                    if (knownTypeList != null)
                    { 
                        knownTypeCollection = new ReadOnlyCollection(knownTypeList);
                    } 
                    else 
                    {
                        knownTypeCollection = new ReadOnlyCollection(Globals.EmptyTypeArray); 
                    }
                }
                return knownTypeCollection;
            } 
        }
 
        internal override DataContractDictionary KnownDataContracts 
        {
            get 
            {
                if (this.knownDataContracts == null && this.knownTypeList != null)
                {
                    // This assignment may be performed concurrently and thus is a race condition. 
                    // It's safe, however, because at worse a new (and identical) dictionary of
                    // data contracts will be created and re-assigned to this field.  Introduction 
                    // of a lock here could lead to deadlocks. 
                    this.knownDataContracts = XmlObjectSerializerContext.GetDataContractsForKnownTypes(this.knownTypeList);
                } 
                return this.knownDataContracts;
            }
        }
 
        public int MaxItemsInObjectGraph
        { 
            get { return maxItemsInObjectGraph; } 
        }
 
        internal bool AlwaysEmitTypeInformation
        {
            get
            { 
                return alwaysEmitTypeInformation;
            } 
        } 

        DataContract RootContract 
        {
            get
            {
                if (rootContract == null) 
                {
                    rootContract = DataContract.GetDataContract(((dataContractSurrogate == null) ? rootType : 
                        DataContractSerializer.GetSurrogatedType(dataContractSurrogate, rootType))); 
                    CheckIfTypeIsReference(rootContract);
                } 
                return rootContract;
            }
        }
 
        XmlDictionaryString RootName
        { 
            get 
            {
                return rootName ?? JsonGlobals.rootDictionaryString; 
            }
        }

        public override bool IsStartObject(XmlReader reader) 
        {
            return IsStartObjectHandleExceptions(new JsonReaderDelegator(reader)); 
        } 

        public override bool IsStartObject(XmlDictionaryReader reader) 
        {
            return IsStartObjectHandleExceptions(new JsonReaderDelegator(reader));
        }
 
        public override object ReadObject(Stream stream)
        { 
            CheckNull(stream, "stream"); 
            return ReadObject(JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max));
        } 

        public override object ReadObject(XmlReader reader)
        {
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), true); 
        }
 
        public override object ReadObject(XmlReader reader, bool verifyObjectName) 
        {
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), verifyObjectName); 
        }

        public override object ReadObject(XmlDictionaryReader reader)
        { 
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), true); // verifyObjectName
        } 
 
        public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
        { 
            return ReadObjectHandleExceptions(new JsonReaderDelegator(reader), verifyObjectName);
        }

        public override void WriteEndObject(XmlWriter writer) 
        {
            WriteEndObjectHandleExceptions(new JsonWriterDelegator(writer)); 
        } 

        public override void WriteEndObject(XmlDictionaryWriter writer) 
        {
            WriteEndObjectHandleExceptions(new JsonWriterDelegator(writer));
        }
 

        public override void WriteObject(Stream stream, object graph) 
        { 
            CheckNull(stream, "stream");
            XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false); //  ownsStream 
            WriteObject(jsonWriter, graph);
            jsonWriter.Flush();
        }
 
        public override void WriteObject(XmlWriter writer, object graph)
        { 
            WriteObjectHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }
 
        public override void WriteObject(XmlDictionaryWriter writer, object graph)
        {
            WriteObjectHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 

        public override void WriteObjectContent(XmlWriter writer, object graph) 
        { 
            WriteObjectContentHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 

        public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
        {
            WriteObjectContentHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }
 
        public override void WriteStartObject(XmlWriter writer, object graph) 
        {
            WriteStartObjectHandleExceptions(new JsonWriterDelegator(writer), graph); 
        }

        public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
        { 
            WriteStartObjectHandleExceptions(new JsonWriterDelegator(writer), graph);
        } 
 
        internal static bool CheckIfJsonNameRequiresMapping(string jsonName)
        { 
            if (jsonName != null)
            {
                if (!DataContract.IsValidNCName(jsonName))
                { 
                    return true;
                } 
 
                for (int i = 0; i < jsonName.Length; i++)
                { 
                    if (XmlJsonWriter.CharacterNeedsEscaping(jsonName[i]))
                    {
                        return true;
                    } 
                }
            } 
            return false; 
        }
 
        internal static bool CheckIfJsonNameRequiresMapping(XmlDictionaryString jsonName)
        {
            return (jsonName == null) ? false : CheckIfJsonNameRequiresMapping(jsonName.Value);
        } 

        internal static bool CheckIfXmlNameRequiresMapping(string xmlName) 
        { 
            return (xmlName == null) ? false : CheckIfJsonNameRequiresMapping(ConvertXmlNameToJsonName(xmlName));
        } 

        internal static bool CheckIfXmlNameRequiresMapping(XmlDictionaryString xmlName)
        {
            return (xmlName == null) ? false : CheckIfXmlNameRequiresMapping(xmlName.Value); 
        }
 
        internal static string ConvertXmlNameToJsonName(string xmlName) 
        {
            return XmlConvert.DecodeName(xmlName); 
        }

        internal static XmlDictionaryString ConvertXmlNameToJsonName(XmlDictionaryString xmlName)
        { 
            return (xmlName == null) ? null : new XmlDictionary().Add(ConvertXmlNameToJsonName(xmlName.Value));
        } 
 
        internal static bool IsJsonLocalName(XmlReaderDelegator reader, string elementName)
        { 
            string name;
            if (XmlObjectSerializerReadContextComplexJson.TryGetJsonLocalName(reader, out name))
            {
                return (elementName == name); 
            }
            return false; 
        } 

        internal static object ReadJsonValue(DataContract contract, XmlReaderDelegator reader, XmlObjectSerializerReadContextComplexJson context) 
        {
            return JsonDataContract.GetJsonDataContract(contract).ReadJsonValue(reader, context);
        }
 
        internal static void WriteJsonNull(XmlWriterDelegator writer)
        { 
            writer.WriteAttributeString(null, JsonGlobals.typeString, null, JsonGlobals.nullString); //  prefix //  namespace 
        }
 
        internal static void WriteJsonValue(JsonDataContract contract, XmlWriterDelegator writer, object graph, XmlObjectSerializerWriteContextComplexJson context, RuntimeTypeHandle declaredTypeHandle)
        {
            contract.WriteJsonValue(writer, graph, context, declaredTypeHandle);
        } 

        internal override Type GetDeserializeType() 
        { 
            return rootType;
        } 

        internal override Type GetSerializeType(object graph)
        {
            return (graph == null) ? rootType : graph.GetType(); 
        }
 
        internal override bool InternalIsStartObject(XmlReaderDelegator reader) 
        {
            if (IsRootElement(reader, RootContract, RootName, XmlDictionaryString.Empty)) 
            {
                return true;
            }
 
            return IsJsonLocalName(reader, RootName.Value);
        } 
 
        internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName)
        { 
            if (MaxItemsInObjectGraph == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
            } 

            if (verifyObjectName) 
            { 
                if (!InternalIsStartObject(xmlReader))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExpectingElement, XmlDictionaryString.Empty, RootName), xmlReader));
                }
            }
            else if (!IsStartElement(xmlReader)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExpectingElementAtDeserialize, XmlNodeType.Element), xmlReader)); 
            } 

            DataContract contract = RootContract; 
            if (contract.IsPrimitive && object.ReferenceEquals(contract.UnderlyingType, rootType))// handle Nullable differently
            {
                return DataContractJsonSerializer.ReadJsonValue(contract, xmlReader, null);
            } 

            XmlObjectSerializerReadContextComplexJson context = XmlObjectSerializerReadContextComplexJson.CreateContext(this, contract); 
            return context.InternalDeserialize(xmlReader, rootType, contract, null, null); 
        }
 
        internal override void InternalWriteEndObject(XmlWriterDelegator writer)
        {
            writer.WriteEndElement();
        } 

        internal override void InternalWriteObject(XmlWriterDelegator writer, object graph) 
        { 
            InternalWriteStartObject(writer, graph);
            InternalWriteObjectContent(writer, graph); 
            InternalWriteEndObject(writer);
        }

        internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph) 
        {
            if (MaxItemsInObjectGraph == 0) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
            } 

            DataContract contract = RootContract;
            Type declaredType = contract.UnderlyingType;
            Type graphType = (graph == null) ? declaredType : graph.GetType(); 

            if (dataContractSurrogate != null) 
            { 
                graph = DataContractSerializer.SurrogateToDataContractType(dataContractSurrogate, graph, declaredType, ref graphType);
            } 

            if (graph == null)
            {
                WriteJsonNull(writer); 
            }
            else 
            { 
                if (declaredType == graphType)
                { 
                    if (contract.CanContainReferences)
                    {
                        XmlObjectSerializerWriteContextComplexJson context = XmlObjectSerializerWriteContextComplexJson.CreateContext(this, contract);
                        context.OnHandleReference(writer, graph, true); //  canContainReferences 
                        context.SerializeWithoutXsiType(contract, writer, graph, declaredType.TypeHandle);
                    } 
                    else 
                    {
                        DataContractJsonSerializer.WriteJsonValue(JsonDataContract.GetJsonDataContract(contract), writer, graph, null, declaredType.TypeHandle); //  XmlObjectSerializerWriteContextComplexJson 
                    }
                }
                else
                { 
                    XmlObjectSerializerWriteContextComplexJson context = XmlObjectSerializerWriteContextComplexJson.CreateContext(this, RootContract);
                    contract = DataContractJsonSerializer.GetDataContract(contract, declaredType, graphType); 
                    if (contract.CanContainReferences) 
                    {
                        context.OnHandleReference(writer, graph, true); //  canContainCyclicReference 
                        context.SerializeWithXsiTypeAtTopLevel(contract, writer, graph, declaredType.TypeHandle, graphType);
                    }
                    else
                    { 
                        context.SerializeWithoutXsiType(contract, writer, graph, declaredType.TypeHandle);
                    } 
                } 
            }
        } 

        internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
        {
            if (this.rootNameRequiresMapping) 
            {
                writer.WriteStartElement("a", JsonGlobals.itemString, JsonGlobals.itemString); 
                writer.WriteAttributeString(null, JsonGlobals.itemString, null, RootName.Value); 
            }
            else 
            {
                writer.WriteStartElement(RootName, XmlDictionaryString.Empty);
            }
        } 

        void AddCollectionItemTypeToKnownTypes(Type knownType) 
        { 
            Type itemType;
            Type typeToCheck = knownType; 
            while (CollectionDataContract.IsCollection(typeToCheck, out itemType))
            {
                if (itemType.IsGenericType && (itemType.GetGenericTypeDefinition() == Globals.TypeOfKeyValue))
                { 
                    itemType = Globals.TypeOfKeyValuePair.MakeGenericType(itemType.GetGenericArguments());
                } 
                this.knownTypeList.Add(itemType); 
                typeToCheck = itemType;
            } 
        }

        void Initialize(Type type,
            IEnumerable knownTypes, 
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate, 
            bool alwaysEmitTypeInformation)
        { 
            CheckNull(type, "type");
            this.rootType = type;

            if (knownTypes != null) 
            {
                this.knownTypeList = new List(); 
                foreach (Type knownType in knownTypes) 
                {
                    this.knownTypeList.Add(knownType); 
                    if (knownType != null)
                    {
                        AddCollectionItemTypeToKnownTypes(knownType);
                    } 
                }
            } 
 
            if (maxItemsInObjectGraph < 0)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxItemsInObjectGraph", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
            }
            this.maxItemsInObjectGraph = maxItemsInObjectGraph;
            this.ignoreExtensionDataObject = ignoreExtensionDataObject; 
            this.dataContractSurrogate = dataContractSurrogate;
            this.alwaysEmitTypeInformation = alwaysEmitTypeInformation; 
        } 

        void Initialize(Type type, 
            XmlDictionaryString rootName,
            IEnumerable knownTypes,
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject, 
            IDataContractSurrogate dataContractSurrogate,
            bool alwaysEmitTypeInformation) 
        { 
            Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
            this.rootName = ConvertXmlNameToJsonName(rootName); 
            this.rootNameRequiresMapping = CheckIfJsonNameRequiresMapping(this.rootName);
        }

        internal static void CheckIfTypeIsReference(DataContract dataContract) 
        {
            if (dataContract.IsReference) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    XmlObjectSerializer.CreateSerializationException(SR.GetString( 
                        SR.JsonUnsupportedForIsReference,
                        DataContract.GetClrTypeFullName(dataContract.UnderlyingType),
                        dataContract.IsReference)));
            } 
        }
 
        internal static DataContract GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType) 
        {
            DataContract contract = DataContractSerializer.GetDataContract(declaredTypeContract, declaredType, objectType); 
            CheckIfTypeIsReference(contract);
            return contract;
        }
    } 
}

// 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