PlainXmlSerializer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataWeb / Server / System / Data / Services / Serializers / PlainXmlSerializer.cs / 1 / PlainXmlSerializer.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a serializer for non-reference entities in plain XML.
//  
// 
// @owner [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Serializers
{
    #region Namespaces. 

    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Data.Services.Providers; 
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Xml; 

    #endregion Namespaces. 
 
    /// This class serializes primitive and complex type as name/value pairs.
    internal sealed class PlainXmlSerializer : Serializer 
    {
        /// Writer to which output is sent.
        private XmlWriter writer;
 
        /// Initializes a new SyndicationSerializer instance.
        /// Description of request. 
        /// Base URI from which resources should be resolved. 
        /// Service with configuration and provider from which metadata should be gathered.
        /// Output stream. 
        /// Encoding for output.
        internal PlainXmlSerializer(
            RequestDescription requestDescription,
            Uri absoluteServiceUri, 
            IDataService service,
            Stream output, 
            Encoding encoding) 
            : base(requestDescription, absoluteServiceUri, service, null)
        { 
            Debug.Assert(output != null, "output != null");
            Debug.Assert(encoding != null, "encoding != null");

            this.writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(output, encoding); 
        }
 
        /// Serializes exception information. 
        /// Description of exception to serialize.
        public override void WriteException(HandleExceptionArgs args) 
        {
            ErrorHandler.SerializeXmlError(args, this.writer);
        }
 
        /// Converts the specified value to a serializable string.
        /// Non-null value to convert. 
        /// The specified value converted to a serializable string. 
        internal static string PrimitiveToString(object value)
        { 
            Debug.Assert(value != null, "value != null");
            string result;
            if (!System.Data.Services.Parsing.WebConvert.TryXmlPrimitiveToString(value, out result))
            { 
                throw new InvalidOperationException(Strings.Serializer_CannotConvertValue(value));
            } 
 
            return result;
        } 

        /// Writes a property with a null value.
        /// XmlWriter to write to.
        /// Property name. 
        /// Type name for value.
        internal static void WriteNullValue(XmlWriter writer, string propertyName, string expectedTypeName) 
        { 
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(expectedTypeName != null, "expectedTypeName != null");
            WriteStartElementWithType(writer, propertyName, expectedTypeName);
            writer.WriteAttributeString(XmlConstants.AtomNullAttributeName, XmlConstants.DataWebMetadataNamespace, XmlConstants.XmlTrueLiteral);
            writer.WriteEndElement(); 
        }
 
        /// Writes the start tag for a property. 
        /// XmlWriter to write to.
        /// Property name. 
        /// Type name for value.
        internal static void WriteStartElementWithType(XmlWriter writer, string propertyName, string propertyTypeName)
        {
            Debug.Assert(writer != null, "writer != null"); 
            Debug.Assert(propertyName != null, "propertyName != null");
            Debug.Assert(propertyTypeName != null, "expectedType != null"); 
            Debug.Assert( 
                object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName) == (propertyTypeName == XmlConstants.EdmStringTypeName),
                "object equality and string equality are the same for Edm.String"); 
            writer.WriteStartElement(propertyName, XmlConstants.DataWebNamespace);
            if (!object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName))
            {
                writer.WriteAttributeString(XmlConstants.AtomTypeAttributeName, XmlConstants.DataWebMetadataNamespace, propertyTypeName); 
            }
        } 
 
        /// Writes an already-formatted property.
        /// XmlWriter to write to. 
        /// Property name.
        /// Type name for value.
        /// Property value in text form.
        internal static void WriteTextValue(XmlWriter writer, string propertyName, string propertyTypeName, string propertyText) 
        {
            Debug.Assert(writer != null, "writer != null"); 
            Debug.Assert(propertyName != null, "propertyName != null"); 
            WriteStartElementWithType(writer, propertyName, propertyTypeName);
            WebUtil.WriteSpacePreserveAttributeIfNecessary(writer, propertyText); 
            writer.WriteString(propertyText);
            writer.WriteEndElement();
        }
 
        /// Flushes the writer to the underlying stream.
        protected override void Flush() 
        { 
            this.writer.Flush();
        } 

        /// Writes a single top-level element.
        /// Expandd results on the specified .
        /// Element to write, possibly null. 
        protected override void WriteTopLevelElement(IExpandedResult expandedResult, object element)
        { 
            Debug.Assert( 
                element != null || this.RequestDescription.TargetElementType != typeof(object),
                "element != null || this.RequestDescription.TargetElementType != typeof(object) -- we shouldn't serialize null open properties"); 
            Debug.Assert(
                this.RequestDescription.IsSingleResult,
                "this.RequestDescription.IsSingleResult -- primitive collections not currently supported");
            string propertyName = this.RequestDescription.ContainerName; 
            Type elementType = (element == null) ? this.RequestDescription.TargetElementType : element.GetType();
            ResourceType resourceType = this.Provider.GetResourceType(elementType); 
            if (resourceType == null) 
            {
                throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(elementType)); 
            }

            this.WriteValueWithName(element, propertyName, resourceType);
        } 

        /// Writes multiple top-level elements, possibly none. 
        /// Expanded results for elements. 
        /// Enumerator for elements to write.
        /// Whether  was succesfully advanced to the first element. 
        protected override void WriteTopLevelElements(IExpandedResult expanded, IEnumerator elements, bool hasMoved)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult, 
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");
            this.writer.WriteStartElement(this.RequestDescription.ContainerName, XmlConstants.DataWebNamespace); 
            while (hasMoved) 
            {
                object element = elements.Current; 
                Type elementType = (element == null) ? this.RequestDescription.TargetElementType : element.GetType();
                ResourceType resourceType = this.Provider.GetResourceType(elementType);
                if (resourceType == null)
                { 
                    throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(elementType));
                } 
 
                this.WriteValueWithName(element, XmlConstants.XmlCollectionItemElementName, resourceType);
                hasMoved = elements.MoveNext(); 
            }

            this.writer.WriteEndElement();
        } 

        ///  
        /// Write out the uri for the given element 
        /// 
        /// element whose uri needs to be written out. 
        protected override void WriteLink(object element)
        {
            Debug.Assert(element != null, "element != null");
            this.IncrementSegmentResultCount(); 
            ResourceContainer container = this.GetContainerForCurrent(element);
            Uri uri = Serializer.GetUri(element, this.Provider, container, this.AbsoluteServiceUri); 
            this.writer.WriteStartElement(XmlConstants.UriElementName, XmlConstants.DataWebNamespace); 
            this.writer.WriteValue(uri.AbsoluteUri);
            this.writer.WriteEndElement(); 
        }

        /// 
        /// Write out the uri for the given elements 
        /// 
        /// elements whose uri need to be writtne out 
        /// the current state of the enumerator. 
        protected override void WriteLinkCollection(IEnumerator elements, bool hasMoved)
        { 
            this.writer.WriteStartElement(XmlConstants.LinkCollectionElementName, XmlConstants.DataWebNamespace);
            while (hasMoved)
            {
                object element = elements.Current; 
                this.WriteLink(element);
                hasMoved = elements.MoveNext(); 
            } 

            this.writer.WriteEndElement(); 
        }

        /// Writes all the properties of the specified resource or complex object.
        /// Resource or complex object with properties to write out. 
        /// Resource type describing the element type.
        private void WriteObjectProperties(object element, ResourceType resourceType) 
        { 
            Debug.Assert(element != null, "element != null");
            Debug.Assert(resourceType != null, "resourceType != null"); 
            Debug.Assert(resourceType.Type.IsAssignableFrom(element.GetType()), "resourceType.Type.IsAssignableFrom(element.GetType())");

            foreach (ResourceProperty property in resourceType.Properties)
            { 
                string propertyName = property.Name;
                object propertyValue = property.GetValue(element); 
                this.PushSegmentForProperty(property); 

                if (property.TypeKind == ResourceTypeKind.ComplexType) 
                {
                    this.WriteComplexObjectValue(propertyValue, propertyName, property.ResourceType);
                }
                else 
                {
                    Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "property.TypeKind == ResourceTypeKind.Primitive"); 
                    this.WritePrimitiveValue(propertyValue, property.Name, property.ResourceType); 
                }
 
                this.PopSegmentName();
            }

#if ASTORIA_OPEN_OBJECT 
            if (resourceType.IsOpenType)
            { 
                IEnumerable> properties = OpenTypeAttribute.EnumerateOpenProperties(element); 
                foreach (KeyValuePair property in properties)
                { 
                    string propertyName = property.Key;
                    object value = property.Value;
                    if (value == null || value == DBNull.Value)
                    { 
                        continue;
                    } 
 
                    Type valueType = value.GetType();
                    ResourceType propertyResourceType = this.Provider.GetResourceType(valueType); 
                    if (propertyResourceType == null)
                    {
                        continue;
                    } 

                    if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.Primitive) 
                    { 
                        this.WritePrimitiveValue(value, propertyName, propertyResourceType);
                    } 
                    else
                    {
                        if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType)
                        { 
                            Debug.Assert(propertyResourceType.Type == valueType, "propertyResourceType.Type == valueType");
                            this.WriteComplexObjectValue(value, propertyName, propertyResourceType); 
                        } 
                        else
                        { 
                            // Entity references within complex types are not supported - ignore this.
                        }
                    }
                } 
            }
#endif 
        } 

        /// Writes a property with a primitive value. 
        /// Value.
        /// Property name.
        /// Type for element.
        private void WritePrimitiveValue(object element, string propertyName, ResourceType type) 
        {
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(type != null, "type != null"); 

            if (element == null) 
            {
                WriteNullValue(this.writer, propertyName, type.FullName);
                return;
            } 

            string propertyText = PrimitiveToString(element); 
            WriteTextValue(this.writer, propertyName, type.FullName, propertyText); 
        }
 
        /// Writes the value of a complex object.
        /// Element to write.
        /// Property name.
        /// Type for element. 
        private void WriteComplexObjectValue(object element, string propertyName, ResourceType expectedType)
        { 
            Debug.Assert(!String.IsNullOrEmpty(propertyName), "!String.IsNullOrEmpty(propertyName)"); 
            Debug.Assert(expectedType != null, "expectedType != null");
            Debug.Assert(expectedType.ResourceTypeKind == ResourceTypeKind.ComplexType, "Must be complex type"); 

            if (element == null)
            {
                WriteNullValue(this.writer, propertyName, expectedType.FullName); 
                return;
            } 
 
            // Non-value complex types may form a cycle.
            // PERF: we can keep a single element around and save the HashSet initialization 
            // until we find a second complex type - this saves the allocation on trees
            // with shallow (single-level) complex types.
            Type elementType = element.GetType();
            Debug.Assert(!expectedType.Type.IsValueType, "!expectedType.Type.IsValueType -- support for this was removed."); 
            if (this.AddToComplexTypeCollection(element))
            { 
                ResourceType resourceType = this.Provider.GetResourceType(elementType); 
                WriteStartElementWithType(this.writer, propertyName, resourceType.FullName);
                this.WriteObjectProperties(element, resourceType); 
                this.writer.WriteEndElement();
                this.RemoveFromComplexTypeCollection(element);
            }
            else 
            {
                throw new InvalidOperationException(Strings.DataServiceException_GeneralError); 
            } 
        }
 
        /// Writes the  value with the specified name.
        /// Element to write out.
        /// Property name for element.
        /// Type of resource to write. 
        private void WriteValueWithName(object element, string propertyName, ResourceType resourceType)
        { 
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(resourceType != null, "resourceType != null");
 
            if (resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
            {
                this.WritePrimitiveValue(element, propertyName, resourceType);
            } 
            else
            { 
                Debug.Assert( 
                    resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType,
                    "resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType -- POX doesn't support " + resourceType.ResourceTypeKind); 
                this.WriteComplexObjectValue(element, propertyName, resourceType);
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a serializer for non-reference entities in plain XML.
//  
// 
// @owner [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Serializers
{
    #region Namespaces. 

    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Data.Services.Providers; 
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Xml; 

    #endregion Namespaces. 
 
    /// This class serializes primitive and complex type as name/value pairs.
    internal sealed class PlainXmlSerializer : Serializer 
    {
        /// Writer to which output is sent.
        private XmlWriter writer;
 
        /// Initializes a new SyndicationSerializer instance.
        /// Description of request. 
        /// Base URI from which resources should be resolved. 
        /// Service with configuration and provider from which metadata should be gathered.
        /// Output stream. 
        /// Encoding for output.
        internal PlainXmlSerializer(
            RequestDescription requestDescription,
            Uri absoluteServiceUri, 
            IDataService service,
            Stream output, 
            Encoding encoding) 
            : base(requestDescription, absoluteServiceUri, service, null)
        { 
            Debug.Assert(output != null, "output != null");
            Debug.Assert(encoding != null, "encoding != null");

            this.writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(output, encoding); 
        }
 
        /// Serializes exception information. 
        /// Description of exception to serialize.
        public override void WriteException(HandleExceptionArgs args) 
        {
            ErrorHandler.SerializeXmlError(args, this.writer);
        }
 
        /// Converts the specified value to a serializable string.
        /// Non-null value to convert. 
        /// The specified value converted to a serializable string. 
        internal static string PrimitiveToString(object value)
        { 
            Debug.Assert(value != null, "value != null");
            string result;
            if (!System.Data.Services.Parsing.WebConvert.TryXmlPrimitiveToString(value, out result))
            { 
                throw new InvalidOperationException(Strings.Serializer_CannotConvertValue(value));
            } 
 
            return result;
        } 

        /// Writes a property with a null value.
        /// XmlWriter to write to.
        /// Property name. 
        /// Type name for value.
        internal static void WriteNullValue(XmlWriter writer, string propertyName, string expectedTypeName) 
        { 
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(expectedTypeName != null, "expectedTypeName != null");
            WriteStartElementWithType(writer, propertyName, expectedTypeName);
            writer.WriteAttributeString(XmlConstants.AtomNullAttributeName, XmlConstants.DataWebMetadataNamespace, XmlConstants.XmlTrueLiteral);
            writer.WriteEndElement(); 
        }
 
        /// Writes the start tag for a property. 
        /// XmlWriter to write to.
        /// Property name. 
        /// Type name for value.
        internal static void WriteStartElementWithType(XmlWriter writer, string propertyName, string propertyTypeName)
        {
            Debug.Assert(writer != null, "writer != null"); 
            Debug.Assert(propertyName != null, "propertyName != null");
            Debug.Assert(propertyTypeName != null, "expectedType != null"); 
            Debug.Assert( 
                object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName) == (propertyTypeName == XmlConstants.EdmStringTypeName),
                "object equality and string equality are the same for Edm.String"); 
            writer.WriteStartElement(propertyName, XmlConstants.DataWebNamespace);
            if (!object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName))
            {
                writer.WriteAttributeString(XmlConstants.AtomTypeAttributeName, XmlConstants.DataWebMetadataNamespace, propertyTypeName); 
            }
        } 
 
        /// Writes an already-formatted property.
        /// XmlWriter to write to. 
        /// Property name.
        /// Type name for value.
        /// Property value in text form.
        internal static void WriteTextValue(XmlWriter writer, string propertyName, string propertyTypeName, string propertyText) 
        {
            Debug.Assert(writer != null, "writer != null"); 
            Debug.Assert(propertyName != null, "propertyName != null"); 
            WriteStartElementWithType(writer, propertyName, propertyTypeName);
            WebUtil.WriteSpacePreserveAttributeIfNecessary(writer, propertyText); 
            writer.WriteString(propertyText);
            writer.WriteEndElement();
        }
 
        /// Flushes the writer to the underlying stream.
        protected override void Flush() 
        { 
            this.writer.Flush();
        } 

        /// Writes a single top-level element.
        /// Expandd results on the specified .
        /// Element to write, possibly null. 
        protected override void WriteTopLevelElement(IExpandedResult expandedResult, object element)
        { 
            Debug.Assert( 
                element != null || this.RequestDescription.TargetElementType != typeof(object),
                "element != null || this.RequestDescription.TargetElementType != typeof(object) -- we shouldn't serialize null open properties"); 
            Debug.Assert(
                this.RequestDescription.IsSingleResult,
                "this.RequestDescription.IsSingleResult -- primitive collections not currently supported");
            string propertyName = this.RequestDescription.ContainerName; 
            Type elementType = (element == null) ? this.RequestDescription.TargetElementType : element.GetType();
            ResourceType resourceType = this.Provider.GetResourceType(elementType); 
            if (resourceType == null) 
            {
                throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(elementType)); 
            }

            this.WriteValueWithName(element, propertyName, resourceType);
        } 

        /// Writes multiple top-level elements, possibly none. 
        /// Expanded results for elements. 
        /// Enumerator for elements to write.
        /// Whether  was succesfully advanced to the first element. 
        protected override void WriteTopLevelElements(IExpandedResult expanded, IEnumerator elements, bool hasMoved)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult, 
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");
            this.writer.WriteStartElement(this.RequestDescription.ContainerName, XmlConstants.DataWebNamespace); 
            while (hasMoved) 
            {
                object element = elements.Current; 
                Type elementType = (element == null) ? this.RequestDescription.TargetElementType : element.GetType();
                ResourceType resourceType = this.Provider.GetResourceType(elementType);
                if (resourceType == null)
                { 
                    throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(elementType));
                } 
 
                this.WriteValueWithName(element, XmlConstants.XmlCollectionItemElementName, resourceType);
                hasMoved = elements.MoveNext(); 
            }

            this.writer.WriteEndElement();
        } 

        ///  
        /// Write out the uri for the given element 
        /// 
        /// element whose uri needs to be written out. 
        protected override void WriteLink(object element)
        {
            Debug.Assert(element != null, "element != null");
            this.IncrementSegmentResultCount(); 
            ResourceContainer container = this.GetContainerForCurrent(element);
            Uri uri = Serializer.GetUri(element, this.Provider, container, this.AbsoluteServiceUri); 
            this.writer.WriteStartElement(XmlConstants.UriElementName, XmlConstants.DataWebNamespace); 
            this.writer.WriteValue(uri.AbsoluteUri);
            this.writer.WriteEndElement(); 
        }

        /// 
        /// Write out the uri for the given elements 
        /// 
        /// elements whose uri need to be writtne out 
        /// the current state of the enumerator. 
        protected override void WriteLinkCollection(IEnumerator elements, bool hasMoved)
        { 
            this.writer.WriteStartElement(XmlConstants.LinkCollectionElementName, XmlConstants.DataWebNamespace);
            while (hasMoved)
            {
                object element = elements.Current; 
                this.WriteLink(element);
                hasMoved = elements.MoveNext(); 
            } 

            this.writer.WriteEndElement(); 
        }

        /// Writes all the properties of the specified resource or complex object.
        /// Resource or complex object with properties to write out. 
        /// Resource type describing the element type.
        private void WriteObjectProperties(object element, ResourceType resourceType) 
        { 
            Debug.Assert(element != null, "element != null");
            Debug.Assert(resourceType != null, "resourceType != null"); 
            Debug.Assert(resourceType.Type.IsAssignableFrom(element.GetType()), "resourceType.Type.IsAssignableFrom(element.GetType())");

            foreach (ResourceProperty property in resourceType.Properties)
            { 
                string propertyName = property.Name;
                object propertyValue = property.GetValue(element); 
                this.PushSegmentForProperty(property); 

                if (property.TypeKind == ResourceTypeKind.ComplexType) 
                {
                    this.WriteComplexObjectValue(propertyValue, propertyName, property.ResourceType);
                }
                else 
                {
                    Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "property.TypeKind == ResourceTypeKind.Primitive"); 
                    this.WritePrimitiveValue(propertyValue, property.Name, property.ResourceType); 
                }
 
                this.PopSegmentName();
            }

#if ASTORIA_OPEN_OBJECT 
            if (resourceType.IsOpenType)
            { 
                IEnumerable> properties = OpenTypeAttribute.EnumerateOpenProperties(element); 
                foreach (KeyValuePair property in properties)
                { 
                    string propertyName = property.Key;
                    object value = property.Value;
                    if (value == null || value == DBNull.Value)
                    { 
                        continue;
                    } 
 
                    Type valueType = value.GetType();
                    ResourceType propertyResourceType = this.Provider.GetResourceType(valueType); 
                    if (propertyResourceType == null)
                    {
                        continue;
                    } 

                    if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.Primitive) 
                    { 
                        this.WritePrimitiveValue(value, propertyName, propertyResourceType);
                    } 
                    else
                    {
                        if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType)
                        { 
                            Debug.Assert(propertyResourceType.Type == valueType, "propertyResourceType.Type == valueType");
                            this.WriteComplexObjectValue(value, propertyName, propertyResourceType); 
                        } 
                        else
                        { 
                            // Entity references within complex types are not supported - ignore this.
                        }
                    }
                } 
            }
#endif 
        } 

        /// Writes a property with a primitive value. 
        /// Value.
        /// Property name.
        /// Type for element.
        private void WritePrimitiveValue(object element, string propertyName, ResourceType type) 
        {
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(type != null, "type != null"); 

            if (element == null) 
            {
                WriteNullValue(this.writer, propertyName, type.FullName);
                return;
            } 

            string propertyText = PrimitiveToString(element); 
            WriteTextValue(this.writer, propertyName, type.FullName, propertyText); 
        }
 
        /// Writes the value of a complex object.
        /// Element to write.
        /// Property name.
        /// Type for element. 
        private void WriteComplexObjectValue(object element, string propertyName, ResourceType expectedType)
        { 
            Debug.Assert(!String.IsNullOrEmpty(propertyName), "!String.IsNullOrEmpty(propertyName)"); 
            Debug.Assert(expectedType != null, "expectedType != null");
            Debug.Assert(expectedType.ResourceTypeKind == ResourceTypeKind.ComplexType, "Must be complex type"); 

            if (element == null)
            {
                WriteNullValue(this.writer, propertyName, expectedType.FullName); 
                return;
            } 
 
            // Non-value complex types may form a cycle.
            // PERF: we can keep a single element around and save the HashSet initialization 
            // until we find a second complex type - this saves the allocation on trees
            // with shallow (single-level) complex types.
            Type elementType = element.GetType();
            Debug.Assert(!expectedType.Type.IsValueType, "!expectedType.Type.IsValueType -- support for this was removed."); 
            if (this.AddToComplexTypeCollection(element))
            { 
                ResourceType resourceType = this.Provider.GetResourceType(elementType); 
                WriteStartElementWithType(this.writer, propertyName, resourceType.FullName);
                this.WriteObjectProperties(element, resourceType); 
                this.writer.WriteEndElement();
                this.RemoveFromComplexTypeCollection(element);
            }
            else 
            {
                throw new InvalidOperationException(Strings.DataServiceException_GeneralError); 
            } 
        }
 
        /// Writes the  value with the specified name.
        /// Element to write out.
        /// Property name for element.
        /// Type of resource to write. 
        private void WriteValueWithName(object element, string propertyName, ResourceType resourceType)
        { 
            Debug.Assert(propertyName != null, "propertyName != null"); 
            Debug.Assert(resourceType != null, "resourceType != null");
 
            if (resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
            {
                this.WritePrimitiveValue(element, propertyName, resourceType);
            } 
            else
            { 
                Debug.Assert( 
                    resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType,
                    "resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType -- POX doesn't support " + resourceType.ResourceTypeKind); 
                this.WriteComplexObjectValue(element, propertyName, resourceType);
            }
        }
    } 
}

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