Exemplo n.º 1
0
        /// <summary>
        /// Writes a collection item (either primitive or complex)
        /// </summary>
        /// <param name="item">The collection item to write.</param>
        protected override void WriteItemImplementation(object item)
        {
            if (item == null)
            {
                this.jsonWriter.WriteValue(null);
            }
            else
            {
                ODataComplexValue complexValue = item as ODataComplexValue;
                if (complexValue != null)
                {
                    ODataJsonWriterUtils.WriteComplexValue(this.jsonWriter, this.MetadataProvider, complexValue, null, false, this.Version);
                }
                else
                {
                    ODataMultiValue multiValue = item as ODataMultiValue;
                    if (multiValue != null)
                    {
                        throw new ODataException(Strings.ODataCollectionWriter_MultiValuesNotSupportedInCollections);
                    }

                    ODataJsonWriterUtils.WritePrimitiveValue(this.jsonWriter, item, null);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Writes a name/value pair for a property.
        /// </summary>
        /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="property">The property to write out.</param>
        /// <param name="owningType">The type owning the property (or null if no metadata is available).</param>
        /// <param name="version">The protocol version used for writing.</param>
        private static void WriteProperty(
            JsonWriter jsonWriter,
            DataServiceMetadataProviderWrapper metadata,
            ODataProperty property,
            ResourceType owningType,
            ODataVersion version)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(jsonWriter != null, "jsonWriter != null");

            ValidationUtils.ValidateProperty(property);
            ResourceProperty resourceProperty   = ValidationUtils.ValidatePropertyDefined(property.Name, owningType);
            bool             isOpenPropertyType = owningType != null && owningType.IsOpenType && resourceProperty == null;

            jsonWriter.WriteName(property.Name);
            object value = property.Value;

            if (value == null)
            {
                // verify that MultiValue properties are not null
                if (resourceProperty != null && resourceProperty.Kind == ResourcePropertyKind.MultiValue)
                {
                    throw new ODataException(Strings.ODataWriter_MultiValuePropertiesMustNotHaveNullValue(resourceProperty.Name));
                }

                jsonWriter.WriteValue(null);
            }
            else
            {
                ResourceType      resourcePropertyType = resourceProperty == null ? null : resourceProperty.ResourceType;
                ODataComplexValue complexValue         = value as ODataComplexValue;
                if (complexValue != null)
                {
                    WriteComplexValue(jsonWriter, metadata, complexValue, resourcePropertyType, isOpenPropertyType, version);
                }
                else
                {
                    ODataMultiValue multiValue = value as ODataMultiValue;
                    if (multiValue != null)
                    {
                        ODataVersionChecker.CheckMultiValueProperties(version, property.Name);
                        WriteMultiValue(jsonWriter, metadata, multiValue, resourcePropertyType, isOpenPropertyType, version);
                    }
                    else
                    {
                        WritePrimitiveValue(jsonWriter, value, resourcePropertyType);
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns the items for the specified multivalue.
        /// </summary>
        /// <param name="epmValueCache">The EPM value cache to use (can be null).</param>
        /// <param name="sourcePathSegment">The source path segment for the property which has this multivalue.</param>
        /// <param name="multiValue">The multivalue to get the items for.</param>
        /// <param name="writingContent">If we're writing content of an entry or not.</param>
        /// <returns>The items enumeration for the multivalue.</returns>
        internal static IEnumerable GetMultiValueItems(
            EpmValueCache epmValueCache,
            EpmSourcePathSegment sourcePathSegment,
            ODataMultiValue multiValue,
            bool writingContent)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(multiValue != null, "multiValue != null");
            Debug.Assert(writingContent || epmValueCache != null, "If we're not writing content, then the EPM value cache must exist.");

            if (epmValueCache == null)
            {
                return(multiValue.Items);
            }
            else
            {
                return(epmValueCache.GetMultiValueItems(sourcePathSegment, multiValue, writingContent));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns the items for the specified multivalue.
        /// </summary>
        /// <param name="epmValueCache">The EPM value cache to use (can be null).</param>
        /// <param name="sourcePathSegment">The source path segment for the property which has this multivalue.</param>
        /// <param name="multiValue">The multivalue to get the items for.</param>
        /// <param name="writingContent">If we're writing content of an entry or not.</param>
        /// <returns>The items enumeration for the multivalue.</returns>
        internal static IEnumerable GetMultiValueItems(
            EpmValueCache epmValueCache,
            EpmSourcePathSegment sourcePathSegment, 
            ODataMultiValue multiValue, 
            bool writingContent)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(multiValue != null, "multiValue != null");
            Debug.Assert(writingContent || epmValueCache != null, "If we're not writing content, then the EPM value cache must exist.");

            if (epmValueCache == null)
            {
                return multiValue.Items;
            }
            else
            {
                return epmValueCache.GetMultiValueItems(sourcePathSegment, multiValue, writingContent);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Writes a collection item (either primitive or complex)
        /// </summary>
        /// <param name="item">The collection item to write.</param>
        protected override void WriteItemImplementation(object item)
        {
            // <d:element>
            this.writer.WriteStartElement(AtomConstants.ODataCollectionItemElementName, AtomConstants.ODataNamespace);

            if (item == null)
            {
                // NOTE can't use ODataAtomWriterUtils.WriteNullAttribute because that method assumes the
                //      default 'm' prefix for the metadata namespace.
                this.writer.WriteAttributeString(
                    AtomConstants.ODataNullAttributeName,
                    AtomConstants.ODataMetadataNamespace,
                    AtomConstants.AtomTrueLiteral);
            }
            else
            {
                ODataComplexValue complexValue = item as ODataComplexValue;
                if (complexValue != null)
                {
                    ODataAtomWriterUtils.WriteComplexValue(this.writer, this.MetadataProvider, complexValue, null, false, true, this.Version, null, null);
                }
                else
                {
                    ODataMultiValue multiValue = item as ODataMultiValue;
                    if (multiValue != null)
                    {
                        throw new ODataException(Strings.ODataCollectionWriter_MultiValuesNotSupportedInCollections);
                    }

                    ODataAtomWriterUtils.WritePrimitiveValue(this.writer, item, null);
                }
            }

            // </d:element>
            this.writer.WriteEndElement();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns the items for the specified multivalue.
        /// </summary>
        /// <param name="sourcePathSegment">The source path segment for the property which has this multivalue.</param>
        /// <param name="multiValue">The multivalue to get the items for.</param>
        /// <param name="writingContent">true if we're writing entry content or false when writing out-of-content EPM.</param>
        /// <returns>The items enumeration for the multivalue.</returns>
        private IEnumerable GetMultiValueItems(EpmSourcePathSegment sourcePathSegment, ODataMultiValue multiValue, bool writingContent)
        {
            Debug.Assert(writingContent || sourcePathSegment != null, "sourcePathSegment must be specified when writing out-of-content.");
            Debug.Assert(multiValue != null, "multiValue != null");

            // If we're writing into content we don't want to populate the cache if it's not already populated.
            // The goal is to behave the same with and without EPM.
            if (writingContent && this.epmValuesCache == null)
            {
                return(multiValue.Items);
            }

            object cachedItemsValue;

            if (this.epmValuesCache != null && this.epmValuesCache.TryGetValue(sourcePathSegment, out cachedItemsValue))
            {
                Debug.Assert(cachedItemsValue is List <object>, "The cached value for multi value must be a List of object");
                return((IEnumerable)cachedItemsValue);
            }

            IEnumerable   items       = multiValue.Items;
            List <object> cachedItems = null;

            if (items != null)
            {
                cachedItems = new List <object>();
                foreach (object item in items)
                {
                    // If the value is a complex value, store it as EpmMultiValueItemCache instance, so that we have a place
                    // to cache the enumeration of properties on that complex value (and possible other nested complex/multi values).
                    if (item is ODataComplexValue)
                    {
                        cachedItems.Add(new EpmMultiValueItemCache(item));
                    }
                    else
                    {
                        // Otherwise it should be a primitive value and thus we can just cache the value itself as it won't have any children
                        cachedItems.Add(item);
                    }
                }
            }

            if (this.epmValuesCache == null)
            {
                this.epmValuesCache = new Dictionary <EpmSourcePathSegment, object>(ReferenceEqualityComparer <EpmSourcePathSegment> .Instance);
            }

            this.epmValuesCache.Add(sourcePathSegment, cachedItems);
            return(cachedItems);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Returns the items for the specified multivalue.
        /// </summary>
        /// <param name="sourcePathSegment">The source path segment for the property which has this multivalue.</param>
        /// <param name="multiValue">The multivalue to get the items for.</param>
        /// <param name="writingContent">true if we're writing entry content or false when writing out-of-content EPM.</param>
        /// <returns>The items enumeration for the multivalue.</returns>
        private IEnumerable GetMultiValueItems(EpmSourcePathSegment sourcePathSegment, ODataMultiValue multiValue, bool writingContent)
        {
            Debug.Assert(writingContent || sourcePathSegment != null, "sourcePathSegment must be specified when writing out-of-content.");
            Debug.Assert(multiValue != null, "multiValue != null");

            // If we're writing into content we don't want to populate the cache if it's not already populated.
            // The goal is to behave the same with and without EPM.
            if (writingContent && this.epmValuesCache == null)
            {
                return multiValue.Items;
            }

            object cachedItemsValue;
            if (this.epmValuesCache != null && this.epmValuesCache.TryGetValue(sourcePathSegment, out cachedItemsValue))
            {
                Debug.Assert(cachedItemsValue is List<object>, "The cached value for multi value must be a List of object");
                return (IEnumerable)cachedItemsValue;
            }

            IEnumerable items = multiValue.Items;
            List<object> cachedItems = null;
            if (items != null)
            {
                cachedItems = new List<object>();
                foreach (object item in items)
                {
                    // If the value is a complex value, store it as EpmMultiValueItemCache instance, so that we have a place
                    // to cache the enumeration of properties on that complex value (and possible other nested complex/multi values).
                    if (item is ODataComplexValue)
                    {
                        cachedItems.Add(new EpmMultiValueItemCache(item));
                    }
                    else
                    {
                        // Otherwise it should be a primitive value and thus we can just cache the value itself as it won't have any children
                        cachedItems.Add(item);
                    }
                }
            }

            if (this.epmValuesCache == null)
            {
                this.epmValuesCache = new Dictionary<EpmSourcePathSegment, object>(ReferenceEqualityComparer<EpmSourcePathSegment>.Instance);
            }

            this.epmValuesCache.Add(sourcePathSegment, cachedItems);
            return cachedItems;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Writes out the value of a MultiValue property.
        /// </summary>
        /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="multiValue">The bag value to write.</param>
        /// <param name="metadataType">The metadata type for the MultiValue.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="version">The protocol version used for writing.</param>
        private static void WriteMultiValue(
            JsonWriter jsonWriter,
            DataServiceMetadataProviderWrapper metadata,
            ODataMultiValue multiValue,
            ResourceType metadataType,
            bool isOpenPropertyType,
            ODataVersion version)
        {
            Debug.Assert(multiValue != null, "multiValue != null");

            // Start the object scope which will represent the entire MultiValue instance
            jsonWriter.StartObjectScope();

            // "__metadata": { "type": "typename" }
            // If the MultiValue has type information write out the metadata and the type in it.
            string typeName = multiValue.TypeName;

            // resolve the type name to the resource type; if no type name is specified we will use the
            // type inferred from metadata
            ResourceType multiValueType = MetadataUtils.ResolveTypeName(metadata, metadataType, ref typeName, ResourceTypeKind.MultiValue, isOpenPropertyType);

            if (typeName != null)
            {
                // Write the __metadata object
                jsonWriter.WriteName(JsonConstants.ODataMetadataName);
                jsonWriter.StartObjectScope();

                // "type": "typename"
                jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName);
                jsonWriter.WriteValue(typeName);

                // End the __metadata
                jsonWriter.EndObjectScope();
            }

            // "results": [
            // This represents the array of items in the MultiValue
            jsonWriter.WriteDataArrayName();
            jsonWriter.StartArrayScope();

            // Iterate through the MultiValue items and write them out (treat null Items as an empty enumeration)
            IEnumerable items = multiValue.Items;

            if (items != null)
            {
                ResourceType expectedItemType = multiValueType == null ? null : ((MultiValueResourceType)multiValueType).ItemType;

                foreach (object item in items)
                {
                    ValidationUtils.ValidateMultiValueItem(item);

                    ODataComplexValue itemAsComplexValue = item as ODataComplexValue;
                    if (itemAsComplexValue != null)
                    {
                        WriteComplexValue(jsonWriter, metadata, itemAsComplexValue, expectedItemType, false, version);
                    }
                    else
                    {
                        ODataMultiValue itemAsMultiValue = item as ODataMultiValue;
                        if (itemAsMultiValue != null)
                        {
                            throw new ODataException(Strings.ODataWriter_NestedMultiValuesAreNotSupported);
                        }
                        else
                        {
                            WritePrimitiveValue(jsonWriter, item, expectedItemType);
                        }
                    }
                }
            }

            // End the array scope which holds the items
            jsonWriter.EndArrayScope();

            // End the object scope which holds the entire MultiValue
            jsonWriter.EndObjectScope();
        }
        /// <summary>
        /// Write the items in a MultiValue in ATOM format.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="multiValue">The MultiValue to write.</param>
        /// <param name="resourcePropertyType">The resource type of the multi value (or null if not metadata is available).</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="isWritingCollection">True if we are writing a collection instead of an entry.</param>
        /// <param name="version">The protocol version used for writing.</param>
        /// <param name="epmValueCache">Cache of values used in EPM so that we avoid multiple enumerations of properties/items. (can be null)</param>
        /// <param name="epmSourcePathSegment">The EPM source path segment which points to the multivalue property we're writing. (can be null)</param>
        private static void WriteMultiValue(
            XmlWriter writer,
            DataServiceMetadataProviderWrapper metadata,
            ODataMultiValue multiValue, 
            ResourceType resourcePropertyType,
            bool isOpenPropertyType,
            bool isWritingCollection,
            ODataVersion version,
            EpmValueCache epmValueCache, 
            EpmSourcePathSegment epmSourcePathSegment)
        {
            Debug.Assert(multiValue != null, "multiValue != null");

            string typeName = multiValue.TypeName;

            // resolve the type name to the resource type; if no type name is specified we will use the 
            // type inferred from metadata
            MultiValueResourceType multiValueType = (MultiValueResourceType)MetadataUtils.ResolveTypeName(metadata, resourcePropertyType, ref typeName, ResourceTypeKind.MultiValue, isOpenPropertyType);

            if (typeName != null)
            {
                WritePropertyTypeAttribute(writer, typeName);
            }

            ResourceType expectedItemType = multiValueType == null ? null : multiValueType.ItemType;

            IEnumerable items = EpmValueCache.GetMultiValueItems(epmValueCache, epmSourcePathSegment, multiValue, true);
            if (items != null)
            {
                foreach (object itemValue in items)
                {
                    object item;
                    EpmMultiValueItemCache epmItemCache = itemValue as EpmMultiValueItemCache;
                    if (epmItemCache != null)
                    {
                        item = epmItemCache.ItemValue;
                    }
                    else
                    {
                        item = itemValue;
                    }

                    ValidationUtils.ValidateMultiValueItem(item);

                    writer.WriteStartElement(AtomConstants.ODataNamespacePrefix, AtomConstants.ODataMultiValueItemElementName, AtomConstants.ODataNamespace);
                    ODataComplexValue complexValue = item as ODataComplexValue;
                    if (complexValue != null)
                    {
                        WriteComplexValue(writer, metadata, complexValue, expectedItemType, false, isWritingCollection, version, epmItemCache, epmSourcePathSegment);
                    }
                    else
                    {
                        ODataMultiValue multiValueItem = item as ODataMultiValue;
                        if (multiValueItem != null)
                        {
                            throw new ODataException(Strings.ODataWriter_NestedMultiValuesAreNotSupported);
                        }
                        else
                        {
                            AtomValueUtils.WritePrimitiveValue(writer, item, expectedItemType);
                        }
                    }

                    writer.WriteEndElement();
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Writes out the value of a MultiValue property.
        /// </summary>
        /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="multiValue">The bag value to write.</param>
        /// <param name="metadataType">The metadata type for the MultiValue.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="version">The protocol version used for writing.</param>
        private static void WriteMultiValue(
            JsonWriter jsonWriter, 
            DataServiceMetadataProviderWrapper metadata, 
            ODataMultiValue multiValue, 
            ResourceType metadataType,
            bool isOpenPropertyType,
            ODataVersion version)
        {
            Debug.Assert(multiValue != null, "multiValue != null");

            // Start the object scope which will represent the entire MultiValue instance
            jsonWriter.StartObjectScope();

            // "__metadata": { "type": "typename" }
            // If the MultiValue has type information write out the metadata and the type in it.
            string typeName = multiValue.TypeName;

            // resolve the type name to the resource type; if no type name is specified we will use the 
            // type inferred from metadata
            ResourceType multiValueType = MetadataUtils.ResolveTypeName(metadata, metadataType, ref typeName, ResourceTypeKind.MultiValue, isOpenPropertyType);

            if (typeName != null)
            {
                // Write the __metadata object
                jsonWriter.WriteName(JsonConstants.ODataMetadataName);
                jsonWriter.StartObjectScope();

                // "type": "typename"
                jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName);
                jsonWriter.WriteValue(typeName);

                // End the __metadata
                jsonWriter.EndObjectScope();
            }

            // "results": [
            // This represents the array of items in the MultiValue
            jsonWriter.WriteDataArrayName();
            jsonWriter.StartArrayScope();

            // Iterate through the MultiValue items and write them out (treat null Items as an empty enumeration)
            IEnumerable items = multiValue.Items;
            if (items != null)
            {
                ResourceType expectedItemType = multiValueType == null ? null : ((MultiValueResourceType)multiValueType).ItemType;

                foreach (object item in items)
                {
                    ValidationUtils.ValidateMultiValueItem(item);

                    ODataComplexValue itemAsComplexValue = item as ODataComplexValue;
                    if (itemAsComplexValue != null)
                    {
                        WriteComplexValue(jsonWriter, metadata, itemAsComplexValue, expectedItemType, false, version);
                    }
                    else
                    {
                        ODataMultiValue itemAsMultiValue = item as ODataMultiValue;
                        if (itemAsMultiValue != null)
                        {
                            throw new ODataException(Strings.ODataWriter_NestedMultiValuesAreNotSupported);
                        }
                        else
                        {
                            WritePrimitiveValue(jsonWriter, item, expectedItemType);
                        }
                    }
                }
            }

            // End the array scope which holds the items
            jsonWriter.EndArrayScope();

            // End the object scope which holds the entire MultiValue
            jsonWriter.EndObjectScope();
        }
Exemplo n.º 11
0
        /// <summary>
        /// Write the items in a MultiValue in ATOM format.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="multiValue">The MultiValue to write.</param>
        /// <param name="resourcePropertyType">The resource type of the multi value (or null if not metadata is available).</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="isWritingCollection">True if we are writing a collection instead of an entry.</param>
        /// <param name="version">The protocol version used for writing.</param>
        /// <param name="epmValueCache">Cache of values used in EPM so that we avoid multiple enumerations of properties/items. (can be null)</param>
        /// <param name="epmSourcePathSegment">The EPM source path segment which points to the multivalue property we're writing. (can be null)</param>
        private static void WriteMultiValue(
            XmlWriter writer,
            DataServiceMetadataProviderWrapper metadata,
            ODataMultiValue multiValue,
            ResourceType resourcePropertyType,
            bool isOpenPropertyType,
            bool isWritingCollection,
            ODataVersion version,
            EpmValueCache epmValueCache,
            EpmSourcePathSegment epmSourcePathSegment)
        {
            Debug.Assert(multiValue != null, "multiValue != null");

            string typeName = multiValue.TypeName;

            // resolve the type name to the resource type; if no type name is specified we will use the
            // type inferred from metadata
            MultiValueResourceType multiValueType = (MultiValueResourceType)MetadataUtils.ResolveTypeName(metadata, resourcePropertyType, ref typeName, ResourceTypeKind.MultiValue, isOpenPropertyType);

            if (typeName != null)
            {
                WritePropertyTypeAttribute(writer, typeName);
            }

            ResourceType expectedItemType = multiValueType == null ? null : multiValueType.ItemType;

            IEnumerable items = EpmValueCache.GetMultiValueItems(epmValueCache, epmSourcePathSegment, multiValue, true);

            if (items != null)
            {
                foreach (object itemValue in items)
                {
                    object item;
                    EpmMultiValueItemCache epmItemCache = itemValue as EpmMultiValueItemCache;
                    if (epmItemCache != null)
                    {
                        item = epmItemCache.ItemValue;
                    }
                    else
                    {
                        item = itemValue;
                    }

                    ValidationUtils.ValidateMultiValueItem(item);

                    writer.WriteStartElement(AtomConstants.ODataNamespacePrefix, AtomConstants.ODataMultiValueItemElementName, AtomConstants.ODataNamespace);
                    ODataComplexValue complexValue = item as ODataComplexValue;
                    if (complexValue != null)
                    {
                        WriteComplexValue(writer, metadata, complexValue, expectedItemType, false, isWritingCollection, version, epmItemCache, epmSourcePathSegment);
                    }
                    else
                    {
                        ODataMultiValue multiValueItem = item as ODataMultiValue;
                        if (multiValueItem != null)
                        {
                            throw new ODataException(Strings.ODataWriter_NestedMultiValuesAreNotSupported);
                        }
                        else
                        {
                            AtomValueUtils.WritePrimitiveValue(writer, item, expectedItemType);
                        }
                    }

                    writer.WriteEndElement();
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Writes a single property in ATOM format.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> to write to.</param>
        /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param>
        /// <param name="property">The property to write out.</param>
        /// <param name="owningType">The type owning the property (or null if no metadata is available).</param>
        /// <param name="version">The protocol version used for writing.</param>
        /// <param name="isTopLevel">True if writing a top-level property payload; otherwise false.</param>
        /// <param name="isWritingCollection">True if we are writing a collection instead of an entry.</param>
        /// <param name="epmValueCache">Cache of values used in EPM so that we avoid multiple enumerations of properties/items. (can be null)</param>
        /// <param name="epmParentSourcePathSegment">The EPM source path segment which points to the property which sub-property we're writing. (can be null)</param>
        internal static void WriteProperty(
            XmlWriter writer,
            DataServiceMetadataProviderWrapper metadata,
            ODataProperty property,
            ResourceType owningType,
            ODataVersion version,
            bool isTopLevel,
            bool isWritingCollection,
            EpmValueCache epmValueCache,
            EpmSourcePathSegment epmParentSourcePathSegment)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");

            ValidationUtils.ValidateProperty(property);
            ResourceProperty resourceProperty = ValidationUtils.ValidatePropertyDefined(property.Name, owningType);

            EpmSourcePathSegment epmSourcePathSegment = null;

            if (epmParentSourcePathSegment != null)
            {
                epmSourcePathSegment = epmParentSourcePathSegment.SubProperties.Where(subProperty => subProperty.PropertyName == property.Name).FirstOrDefault();
            }

            object value = property.Value;

            // TODO: If we implement validation or type conversions the value needs to be converted here
            //       since the next method call needs to know if the value is a string or not in some cases.

            // If EPM tells us to skip this property in content, then we're done here.
            if (!ShouldWritePropertyInContent(value, epmSourcePathSegment, version))
            {
                return;
            }

            // <d:propertyname>
            writer.WriteStartElement(
                isWritingCollection ? string.Empty : AtomConstants.ODataNamespacePrefix,
                property.Name,
                AtomConstants.ODataNamespace);

            if (isTopLevel)
            {
                WriteDefaultNamespaceAttributes(writer, DefaultNamespaceFlags.OData | DefaultNamespaceFlags.ODataMetadata);
            }

            // Null property value.
            if (value == null)
            {
                // verify that MultiValue properties are not null
                if (resourceProperty != null && resourceProperty.Kind == ResourcePropertyKind.MultiValue)
                {
                    throw new ODataException(Strings.ODataWriter_MultiValuePropertiesMustNotHaveNullValue(resourceProperty.Name));
                }

                ODataAtomWriterUtils.WriteNullAttribute(writer);
            }
            else
            {
                ODataComplexValue complexValue         = value as ODataComplexValue;
                ResourceType      resourcePropertyType = resourceProperty == null ? null : resourceProperty.ResourceType;
                bool isOpenPropertyType = owningType != null && owningType.IsOpenType && resourceProperty == null;

                // Complex properties are written recursively.
                if (complexValue != null)
                {
                    WriteComplexValue(writer, metadata, complexValue, resourcePropertyType, isOpenPropertyType, isWritingCollection, version, epmValueCache, epmSourcePathSegment);
                }
                else
                {
                    ODataMultiValue multiValue = value as ODataMultiValue;
                    if (multiValue != null)
                    {
                        ODataVersionChecker.CheckMultiValueProperties(version, property.Name);
                        WriteMultiValue(writer, metadata, multiValue, resourcePropertyType, isOpenPropertyType, isWritingCollection, version, epmValueCache, epmSourcePathSegment);
                    }
                    else
                    {
                        WritePrimitiveValue(writer, value, resourcePropertyType);
                    }
                }
            }

            // </d:propertyname>
            writer.WriteEndElement();
        }
Exemplo n.º 13
0
        private void WriteValue(object value)
        {
            ODataComplexValue complexValue = value as ODataComplexValue;

            if (complexValue != null)
            {
                this.writer.WriteLine("ODataComplexValue");
                this.writer.Indent++;
                this.writer.WriteLine("TypeName: " + (complexValue.TypeName ?? "<null>"));
                this.WriteProperties(complexValue.Properties);
                this.writer.Indent--;

                return;
            }

            ODataMultiValue multiValue = value as ODataMultiValue;

            if (multiValue != null)
            {
                this.writer.WriteLine("ODataMultiValue");
                this.writer.Indent++;
                this.writer.WriteLine("TypeName: " + (multiValue.TypeName ?? "<null>"));
                this.writer.WriteLine("Items:");
                this.writer.Indent++;
                foreach (object item in multiValue.Items)
                {
                    this.WriteValue(item);
                }

                this.writer.Indent--;
                this.writer.Indent--;

                return;
            }

            ODataStreamReferenceValue streamReferenceValue = value as ODataStreamReferenceValue;

            if (streamReferenceValue != null)
            {
                this.writer.WriteLine("ODataStreamReferenceValue");
                this.writer.Indent++;
                if (streamReferenceValue.ReadLink != null)
                {
                    this.writer.WriteLine("ReadLink: " + streamReferenceValue.ReadLink.AbsoluteUri);
                }

                if (streamReferenceValue.EditLink != null)
                {
                    this.writer.WriteLine("EditLink: " + streamReferenceValue.EditLink.AbsoluteUri);
                }

                this.writer.Indent--;

                return;
            }

            if (value == null)
            {
                this.writer.WriteLine("null");
            }
            else
            {
                this.writer.WriteLine(value.ToString());
            }
        }