XmlObjectSerializerWriteContextComplexJson.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 / NetFx35 / System.ServiceModel.Web / System / Runtime / Serialization / Json / XmlObjectSerializerWriteContextComplexJson.cs / 3 / XmlObjectSerializerWriteContextComplexJson.cs

                            using System; 
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection; 
using System.ServiceModel;
using System.Collections; 
 
namespace System.Runtime.Serialization.Json
{ 
#if USE_REFEMIT
 	public class XmlObjectSerializerWriteContextComplexJson : XmlObjectSerializerWriteContextComplex
#else
    internal class XmlObjectSerializerWriteContextComplexJson : XmlObjectSerializerWriteContextComplex 
#endif
    { 
        bool alwaysEmitXsiType; 
        bool perCallXsiTypeAlreadyEmitted;
 
        public XmlObjectSerializerWriteContextComplexJson(DataContractJsonSerializer serializer, DataContract rootTypeDataContract)
            : base(serializer,
            serializer.MaxItemsInObjectGraph,
            new StreamingContext(StreamingContextStates.All), 
            serializer.IgnoreExtensionDataObject)
        { 
            this.alwaysEmitXsiType = serializer.AlwaysEmitTypeInformation; 
            this.rootTypeDataContract = rootTypeDataContract;
            this.serializerKnownTypeList = serializer.knownTypeList; 
            this.serializerKnownDataContracts = serializer.KnownDataContracts;
            this.dataContractSurrogate = serializer.DataContractSurrogate;
        }
 
        internal static XmlObjectSerializerWriteContextComplexJson CreateContext(DataContractJsonSerializer serializer, DataContract rootTypeDataContract)
        { 
            return new XmlObjectSerializerWriteContextComplexJson(serializer, rootTypeDataContract); 
        }
 
        internal IList SerializerKnownTypeList
        {
            get
            { 
                return this.serializerKnownTypeList;
            } 
        } 

        internal override bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, string clrTypeName, string clrAssemblyName) 
        {
            return false;
        }
 
        internal override bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
        { 
            return false; 
        }
 
        internal override void WriteArraySize(XmlWriterDelegator xmlWriter, int size)
        {
        }
 
        protected override void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
        { 
            if (string.IsNullOrEmpty(dataContractNamespace)) 
            {
                WriteTypeInfo(writer, dataContractName); 
            }
            else
            {
                WriteTypeInfo(writer, string.Concat(dataContractName, JsonGlobals.NameValueSeparatorString, TruncateDefaultDataContractNamespace(dataContractNamespace))); 
            }
        } 
 
        internal static string TruncateDefaultDataContractNamespace(string dataContractNamespace)
        { 
            if (!string.IsNullOrEmpty(dataContractNamespace))
            {
                if (dataContractNamespace[0] == '#')
                { 
                    return string.Concat("\\", dataContractNamespace);
                } 
                else if (dataContractNamespace[0] == '\\') 
                {
                    return string.Concat("\\", dataContractNamespace); 
                }
                else if (dataContractNamespace.StartsWith(Globals.DataContractXsdBaseNamespace, StringComparison.Ordinal))
                {
                    return string.Concat("#", dataContractNamespace.Substring(JsonGlobals.DataContractXsdBaseNamespaceLength)); 
                }
            } 
 
            return dataContractNamespace;
        } 

        static bool RequiresJsonTypeInfo(DataContract contract)
        {
            return (contract is ClassDataContract); 
        }
 
        void WriteTypeInfo(XmlWriterDelegator writer, string typeInformation) 
        {
            writer.WriteAttributeString(null, JsonGlobals.serverTypeString, null, typeInformation); 
        }

        protected override bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
        { 
            if (!((object.ReferenceEquals(contract.Name, declaredContract.Name) &&
                   object.ReferenceEquals(contract.Namespace, declaredContract.Namespace)) || 
                 (contract.Name.Value == declaredContract.Name.Value && 
                 contract.Namespace.Value == declaredContract.Namespace.Value)) &&
                 (contract.UnderlyingType != Globals.TypeOfObjectArray)) 
            {
                // We always deserialize collections assigned to System.Object as object[]
                // Because of its common and JSON-specific nature,
                //    we don't want to validate known type information for object[] 

                if (RequiresJsonTypeInfo(contract)) 
                { 
                    perCallXsiTypeAlreadyEmitted = true;
                    WriteTypeInfo(writer, contract.Name.Value, contract.Namespace.Value); 
                }
                // Return true regardless of whether we actually wrote __type information
                // E.g. We don't write __type information for enums, but we still want verifyKnownType
                //      to be true for them. 
                return true;
            } 
            return false; 
        }
 

#if USE_REFEMIT
        public void WriteJsonISerializable(XmlWriterDelegator xmlWriter, ISerializable obj)
#else 
        internal void WriteJsonISerializable(XmlWriterDelegator xmlWriter, ISerializable obj)
#endif 
        { 
            Type objType = obj.GetType();
            SerializationInfo serInfo = new SerializationInfo(objType, XmlObjectSerializer.FormatterConverter); 
            obj.GetObjectData(serInfo, GetStreamingContext());
            if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName)
            {
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR2.GetString(SR2.ChangingFullTypeNameNotSupported, serInfo.FullTypeName, DataContract.GetClrTypeFullName(objType)))); 
            }
            else 
            { 
                base.WriteSerializationInfo(xmlWriter, objType, serInfo);
            } 
        }


#if USE_REFEMIT 
        public static DataContract GetRevisedItemContract(DataContract oldItemContract)
#else 
        internal static DataContract GetRevisedItemContract(DataContract oldItemContract) 
#endif
        { 
            if ((oldItemContract != null) &&
                oldItemContract.UnderlyingType.IsGenericType &&
                (oldItemContract.UnderlyingType.GetGenericTypeDefinition() == Globals.TypeOfKeyValue))
            { 
                return ClassDataContract.CreateClassDataContractForKeyValue(oldItemContract.UnderlyingType, oldItemContract.Namespace, new string[] { JsonGlobals.KeyString, JsonGlobals.ValueString });
            } 
            return oldItemContract; 
        }
 
        protected override void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
        {
            JsonDataContract jsonDataContract = JsonDataContract.GetJsonDataContract(dataContract);
            if (alwaysEmitXsiType && !perCallXsiTypeAlreadyEmitted && RequiresJsonTypeInfo(dataContract)) 
            {
                WriteTypeInfo(xmlWriter, jsonDataContract.TypeName); 
            } 
            perCallXsiTypeAlreadyEmitted = false;
            DataContractJsonSerializer.WriteJsonValue(jsonDataContract, xmlWriter, obj, this, declaredTypeHandle); 
        }

        protected override void WriteNull(XmlWriterDelegator xmlWriter)
        { 
            DataContractJsonSerializer.WriteJsonNull(xmlWriter);
        } 
 
#if USE_REFEMIT
        public XmlDictionaryString CollectionItemName 
#else
        internal XmlDictionaryString CollectionItemName
#endif
        { 
            get { return JsonGlobals.itemDictionaryString; }
        } 
 
#if USE_REFEMIT
        public static void WriteJsonNameWithMapping(XmlWriterDelegator xmlWriter, XmlDictionaryString[] memberNames, int index) 
#else
        internal static void WriteJsonNameWithMapping(XmlWriterDelegator xmlWriter, XmlDictionaryString[] memberNames, int index)
#endif
        { 
            xmlWriter.WriteStartElement("a", JsonGlobals.itemString, JsonGlobals.itemString);
            xmlWriter.WriteAttributeString(null, JsonGlobals.itemString, null, memberNames[index].Value); 
        } 

        internal override void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode) 
        {
            Type dataType = dataNode.DataType;
            if (dataType == Globals.TypeOfClassDataNode ||
                dataType == Globals.TypeOfISerializableDataNode) 
            {
                xmlWriter.WriteAttributeString(null, JsonGlobals.typeString, null, JsonGlobals.objectString); 
                base.WriteExtensionDataTypeInfo(xmlWriter, dataNode); 
            }
            else if (dataType == Globals.TypeOfCollectionDataNode) 
            {
                xmlWriter.WriteAttributeString(null, JsonGlobals.typeString, null, JsonGlobals.arrayString);
                // Don't write __type for collections
            } 
            else if (dataType == Globals.TypeOfXmlDataNode)
            { 
                // Don't write type or __type for XML types because we serialize them to strings 
            }
            else if ((dataType == Globals.TypeOfObject) && (dataNode.Value != null)) 
            {
                DataContract dc = GetDataContract(dataNode.Value.GetType());
                if (RequiresJsonTypeInfo(dc))
                { 
                    base.WriteExtensionDataTypeInfo(xmlWriter, dataNode);
                } 
            } 
        }
 
        protected override void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
        {
            DataContract dataContract;
            bool verifyKnownType = false; 
            bool isDeclaredTypeInterface = declaredType.IsInterface;
 
            if (isDeclaredTypeInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                dataContract = GetDataContract(declaredTypeHandle, declaredType); 
            }
            else if (declaredType.IsArray) // If declared type is array do not write __serverType. Instead write__serverType for each item
            {
                dataContract = GetDataContract(declaredTypeHandle, declaredType); 
            }
            else 
            { 
                dataContract = GetDataContract(objectTypeHandle, objectType);
                DataContract declaredTypeContract = (declaredTypeID >= 0) 
                    ? GetDataContract(declaredTypeID, declaredTypeHandle)
                    : GetDataContract(declaredTypeHandle, declaredType);
                verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
                HandleCollectionAssignedToObject(declaredType, ref dataContract, ref obj, ref verifyKnownType); 
            }
 
            if (isDeclaredTypeInterface) 
            {
                VerifyObjectCompatibilityWithInterface(dataContract, obj, declaredType); 
            }
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredType.TypeHandle);
        }
 
        static void VerifyObjectCompatibilityWithInterface(DataContract contract, object graph, Type declaredType)
        { 
            Type contractType = contract.GetType(); 
            if ((contractType == typeof(XmlDataContract)) && !Globals.TypeOfIXmlSerializable.IsAssignableFrom(declaredType))
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR2.GetString(SR2.XmlObjectAssignedToIncompatibleInterface, graph.GetType(), declaredType)));
            }

            if ((contractType == typeof(CollectionDataContract)) && !CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR2.GetString(SR2.CollectionAssignedToIncompatibleInterface, graph.GetType(), declaredType))); 
            } 
        }
 
        void HandleCollectionAssignedToObject(Type declaredType, ref DataContract dataContract, ref object obj, ref bool verifyKnownType)
        {
            if ((declaredType != dataContract.UnderlyingType) && (dataContract is CollectionDataContract))
            { 
                if (verifyKnownType)
                { 
                    VerifyType(dataContract); 
                    verifyKnownType = false;
                } 
                if (((CollectionDataContract)dataContract).Kind == CollectionKind.Dictionary)
                {
                    // Convert non-generic dictionary to generic dictionary
                    IDictionary dictionaryObj = obj as IDictionary; 
                    Dictionary genericDictionaryObj = new Dictionary();
                    foreach (DictionaryEntry entry in dictionaryObj) 
                    { 
                        genericDictionaryObj.Add(entry.Key, entry.Value);
                    } 
                    obj = genericDictionaryObj;
                }
                dataContract = GetDataContract(Globals.TypeOfIEnumerable);
            } 
        }
 
        internal override void SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle originalDeclaredTypeHandle) 
        {
            bool verifyKnownType = false; 
            Type declaredType = rootTypeDataContract.UnderlyingType;
            bool isDeclaredTypeInterface = declaredType.IsInterface;

            if (!(isDeclaredTypeInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
                && !declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
            { 
                verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, rootTypeDataContract); 
                HandleCollectionAssignedToObject(declaredType, ref dataContract, ref obj, ref verifyKnownType);
            } 

            if (isDeclaredTypeInterface)
            {
                VerifyObjectCompatibilityWithInterface(dataContract, obj, declaredType); 
            }
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredType.TypeHandle); 
        } 

        void VerifyType(DataContract dataContract) 
        {
            bool knownTypesAddedInCurrentScope = false;
            if (dataContract.KnownDataContracts != null)
            { 
                scopedKnownTypes.Push(dataContract.KnownDataContracts);
                knownTypesAddedInCurrentScope = true; 
            } 

            DataContract knownContract = ResolveDataContractFromKnownTypes(dataContract.StableName.Name, dataContract.StableName.Namespace, null /*memberTypeContract*/); 
            if (knownContract == null || knownContract.UnderlyingType != dataContract.UnderlyingType)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DcTypeNotFoundOnSerialize, DataContract.GetClrTypeFullName(dataContract.UnderlyingType), dataContract.StableName.Name, dataContract.StableName.Namespace)));
            } 

            if (knownTypesAddedInCurrentScope) 
            { 
                scopedKnownTypes.Pop();
            } 
        }

        internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
        { 
            DataContract dataContract = base.GetDataContract(typeHandle, type);
            DataContractJsonSerializer.CheckIfTypeIsReference(dataContract); 
            return dataContract; 
        }
 
        internal override DataContract GetDataContractSkipValidation(int typeId, RuntimeTypeHandle typeHandle, Type type)
        {
            DataContract dataContract = base.GetDataContractSkipValidation(typeId, typeHandle, type);
            DataContractJsonSerializer.CheckIfTypeIsReference(dataContract); 
            return dataContract;
        } 
 
        internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
        { 
            DataContract dataContract = base.GetDataContract(id, typeHandle);
            DataContractJsonSerializer.CheckIfTypeIsReference(dataContract);
            return dataContract;
        } 
    }
} 

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