示例#1
0
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, List <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, bool epmPresent)
        {
            if (!base.XmlReader.IsEmptyElement)
            {
                base.XmlReader.ReadStartElement();
                do
                {
                    switch (base.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataNamespace))
                        {
                            IEdmProperty property       = null;
                            bool         flag           = false;
                            bool         ignoreProperty = false;
                            if (structuredType != null)
                            {
                                property = ReaderValidationUtils.ValidateValuePropertyDefined(base.XmlReader.LocalName, structuredType, base.MessageReaderSettings, out ignoreProperty);
                                if ((property != null) && (property.PropertyKind == EdmPropertyKind.Navigation))
                                {
                                    throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(property.Name, structuredType));
                                }
                                flag = property == null;
                            }
                            if (ignoreProperty)
                            {
                                base.XmlReader.Skip();
                            }
                            else
                            {
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = (base.ReadingResponse || (property == null)) ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(property);
                                ODataProperty property2 = this.ReadProperty((property == null) ? null : property.Type, nullValueReadBehaviorKind, epmPresent);
                                if (property2 != null)
                                {
                                    if (flag)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property2.Name, property2.Value);
                                    }
                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property2);
                                    properties.Add(property2);
                                }
                            }
                        }
                        else
                        {
                            base.XmlReader.Skip();
                        }
                        break;

                    case XmlNodeType.EndElement:
                        break;

                    default:
                        base.XmlReader.Skip();
                        break;
                    }
                }while (base.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
示例#2
0
        private void ReadEntryProperty(IODataJsonReaderEntryState entryState, IEdmProperty edmProperty)
        {
            ODataNullValueBehaviorKind kind = base.ReadingResponse ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(edmProperty);
            IEdmTypeReference          type = edmProperty.Type;
            object propertyValue            = type.IsStream() ? this.ReadStreamPropertyValue() : base.ReadNonEntityValue(type, null, null, kind == ODataNullValueBehaviorKind.Default);

            if ((kind != ODataNullValueBehaviorKind.IgnoreValue) || (propertyValue != null))
            {
                AddEntryProperty(entryState, edmProperty.Name, propertyValue);
            }
        }
        /// <summary>
        /// Reads a property.
        /// </summary>
        /// <param name="isTop">whether it is the top level</param>
        /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param>
        /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param>
        /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param>
        /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element - The XML element representing the property to read.
        ///                                        Note that the method does NOT check for the property name neither it resolves the property against metadata.
        /// Post-Condition:  Any                 - The node after the property.
        /// </remarks>
        private ODataProperty ReadProperty(
            bool isTop,
            string expectedPropertyName,
            IEdmTypeReference expectedPropertyTypeReference,
            ODataNullValueBehaviorKind nullValueReadBehaviorKind)
        {
            Debug.Assert(
                expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataEnumTypeKind() ||
                expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(),
                "Only primitive, Enum, complex and collection types can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element);
            this.XmlReader.AssertNotBuffering();

            ODataProperty property     = new ODataProperty();
            string        propertyName = null;

            if (!isTop)
            {
                propertyName = this.XmlReader.LocalName;
                ValidationUtils.ValidatePropertyName(propertyName);
                ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName);
            }

            property.Name = propertyName;

            object propertyValue = this.ReadNonEntityValueImplementation(
                expectedPropertyTypeReference,
                /*duplicatePropertyNamesChecker*/ null,
                /*collectionValidator*/ null,
                nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default,
                propertyName);

            if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null)
            {
                property = null;
            }
            else
            {
                property.Value = propertyValue;
            }

            // Read past the end tag of the property or the start tag if the element is empty.
            this.XmlReader.Read();

            this.XmlReader.AssertNotBuffering();
            return(property);
        }
        /// <summary>
        /// Reads a property.
        /// </summary>
        /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param>
        /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param>
        /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param>
        /// <param name="epmPresent">Whether any EPM mappings exist.</param>
        /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element - The XML element representing the property to read.
        ///                                        Note that the method does NOT check for the property name neither it resolves the property against metadata.
        /// Post-Condition:  Any                 - The node after the property.
        /// </remarks>
        private ODataProperty ReadProperty(
            string expectedPropertyName,
            IEdmTypeReference expectedPropertyTypeReference,
            ODataNullValueBehaviorKind nullValueReadBehaviorKind,
            bool epmPresent)
        {
            Debug.Assert(
                expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() ||
                expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(),
                "Only primitive, complex and collection types can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element);
            Debug.Assert(this.UseServerFormatBehavior || this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace), "Property elements must be in the OData namespace (unless we are running in WCF DS server format mode).");
            this.XmlReader.AssertNotBuffering();

            ODataProperty property     = new ODataProperty();
            string        propertyName = this.XmlReader.LocalName;

            ValidationUtils.ValidatePropertyName(propertyName);
            ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName);
            property.Name = propertyName;

            object propertyValue = this.ReadNonEntityValueImplementation(
                expectedPropertyTypeReference,
                /*duplicatePropertyNamesChecker*/ null,
                /*collectionValidator*/ null,
                nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default,
                epmPresent,
                propertyName);

            if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null)
            {
                property = null;
            }
            else
            {
                property.Value = propertyValue;
            }

            // Read past the end tag of the property or the start tag if the element is empty.
            this.XmlReader.Read();

            this.XmlReader.AssertNotBuffering();
            return(property);
        }
示例#5
0
 /// <summary>
 /// Adds a transient annotation to indicate how null values for the specified property should be read.
 /// </summary>
 /// <param name="model">The <see cref="IEdmModel"/> containing the annotations.</param>
 /// <param name="property">The <see cref="IEdmProperty"/> to modify.</param>
 /// <param name="nullValueReadBehaviorKind">The new behavior for reading null values for this property.</param>
 public static void SetNullValueReaderBehavior(this IEdmModel model, IEdmProperty property, ODataNullValueBehaviorKind nullValueReadBehaviorKind)
 {
     ExceptionUtils.CheckArgumentNotNull(model, "model");
     ExceptionUtils.CheckArgumentNotNull(property, "property");
     
     ODataEdmPropertyAnnotation annotation = model.GetAnnotationValue<ODataEdmPropertyAnnotation>(property);
     if (annotation == null)
     {
         if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.Default)
         {
             annotation = new ODataEdmPropertyAnnotation
             {
                 NullValueReadBehaviorKind = nullValueReadBehaviorKind
             };
             model.SetAnnotationValue(property, annotation);
         }
     }
     else
     {
         annotation.NullValueReadBehaviorKind = nullValueReadBehaviorKind;
     }
 }
示例#6
0
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <param name="epmPresent">Whether any EPM mappings exist.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, List <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, bool epmPresent)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                        {
                            // Found a property
                            IEdmProperty edmProperty    = null;
                            bool         isOpen         = false;
                            bool         ignoreProperty = false;

                            if (structuredType != null)
                            {
                                // Lookup the property in metadata
                                edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                {
                                    throw new ODataException(o.Strings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                }

                                // If the property was not declared, it must be open.
                                isOpen = edmProperty == null;
                            }

                            if (ignoreProperty)
                            {
                                this.XmlReader.Skip();
                            }
                            else
                            {
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                        ? ODataNullValueBehaviorKind.Default
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                ODataProperty property = this.ReadProperty(edmProperty == null ? null : edmProperty.Type, nullValueReadBehaviorKind, epmPresent);
                                Debug.Assert(
                                    property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                    "If we don't ignore null values the property must not be null.");

                                if (property != null)
                                {
                                    if (isOpen)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value);
                                    }

                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                    properties.Add(property);
                                }
                            }
                        }
                        else
                        {
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // End of the complex value.
                        break;

                    default:
                        // Non-element so for example a text node, just ignore
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
示例#7
0
        /// <summary>
        /// Adds a transient annotation to indicate how null values for the specified property should be read.
        /// </summary>
        /// <param name="model">The <see cref="IEdmModel"/> containing the annotations.</param>
        /// <param name="property">The <see cref="IEdmProperty"/> to modify.</param>
        /// <param name="nullValueReadBehaviorKind">The new behavior for reading null values for this property.</param>
        public static void SetNullValueReaderBehavior(this IEdmModel model, IEdmProperty property, ODataNullValueBehaviorKind nullValueReadBehaviorKind)
        {
            ExceptionUtils.CheckArgumentNotNull(model, "model");
            ExceptionUtils.CheckArgumentNotNull(property, "property");

            ODataEdmPropertyAnnotation annotation = model.GetAnnotationValue <ODataEdmPropertyAnnotation>(property);

            if (annotation == null)
            {
                if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.Default)
                {
                    annotation = new ODataEdmPropertyAnnotation
                    {
                        NullValueReadBehaviorKind = nullValueReadBehaviorKind
                    };
                    model.SetAnnotationValue(property, annotation);
                }
            }
            else
            {
                annotation.NullValueReadBehaviorKind = nullValueReadBehaviorKind;
            }
        }
        /// <summary>
        /// Reads a property.
        /// </summary>
        /// <param name="isTop">whether it is the top level</param>
        /// <param name="expectedPropertyName">The expected property name to be read from the payload (or null if no expected property name was specified).</param>
        /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param>
        /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param>
        /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element - The XML element representing the property to read.
        ///                                        Note that the method does NOT check for the property name neither it resolves the property against metadata.
        /// Post-Condition:  Any                 - The node after the property.
        /// </remarks>
        private ODataProperty ReadProperty(
            bool isTop,
            string expectedPropertyName, 
            IEdmTypeReference expectedPropertyTypeReference, 
            ODataNullValueBehaviorKind nullValueReadBehaviorKind)
        {
            Debug.Assert(
                expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() || expectedPropertyTypeReference.IsODataEnumTypeKind() ||
                expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityCollectionType(),
                "Only primitive, Enum, complex and collection types can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element);
            this.XmlReader.AssertNotBuffering();

            ODataProperty property = new ODataProperty();
            string propertyName = null;
            if (!isTop)
            {
                propertyName = this.XmlReader.LocalName;
                ValidationUtils.ValidatePropertyName(propertyName);
                ReaderValidationUtils.ValidateExpectedPropertyName(expectedPropertyName, propertyName);
            }

            property.Name = propertyName;

            object propertyValue = this.ReadNonEntityValueImplementation(
                expectedPropertyTypeReference, 
                /*duplicatePropertyNamesChecker*/ null, 
                /*collectionValidator*/ null,
                nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default,
                propertyName);

            if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null)
            {
                property = null;
            }
            else
            {
                property.Value = propertyValue;
            }

            // Read past the end tag of the property or the start tag if the element is empty.
            this.XmlReader.Read();

            this.XmlReader.AssertNotBuffering();
            return property;
        }
示例#9
0
        /// <summary>
        /// Reads a complex value.
        /// </summary>
        /// <param name="complexValueTypeReference">The expected type reference of the value.</param>
        /// <param name="payloadTypeName">The type name read from the payload.</param>
        /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use - if null the method should create a new one if necessary.</param>
        /// <returns>The value of the complex value.</returns>
        /// <remarks>
        /// Pre-Condition:  Fails if the current node is not a JsonNodeType.StartObject or JsonNodeType.PrimitiveValue (with null value)
        /// Post-Condition: almost anything - the node after the complex value (after the EndObject)
        /// </remarks>
        private ODataComplexValue ReadComplexValueImplementation(
            IEdmComplexTypeReference complexValueTypeReference,
            string payloadTypeName,
            SerializationTypeNameAnnotation serializationTypeNameAnnotation,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            this.JsonReader.AssertNotBuffering();

            this.IncreaseRecursionDepth();

            // Read over the start object
            this.JsonReader.ReadStartObject();

            ODataComplexValue complexValue = new ODataComplexValue();

            complexValue.TypeName = complexValueTypeReference != null?complexValueTypeReference.ODataFullName() : payloadTypeName;

            if (serializationTypeNameAnnotation != null)
            {
                complexValue.SetAnnotation(serializationTypeNameAnnotation);
            }

            if (duplicatePropertyNamesChecker == null)
            {
                duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
            }
            else
            {
                duplicatePropertyNamesChecker.Clear();
            }

            List <ODataProperty> properties = new List <ODataProperty>();
            bool metadataPropertyFound      = false;

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();
                if (string.CompareOrdinal(JsonConstants.ODataMetadataName, propertyName) == 0)
                {
                    // __metadata property.
                    if (metadataPropertyFound)
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonPropertyAndValueDeserializer_MultipleMetadataPropertiesInComplexValue);
                    }

                    metadataPropertyFound = true;

                    this.JsonReader.SkipValue();
                }
                else
                {
                    if (!ValidationUtils.IsValidPropertyName(propertyName))
                    {
                        // We ignore properties with an invalid name since these are extension points for the future.
                        this.JsonReader.SkipValue();
                    }
                    else
                    {
                        // Any other property is data
                        ODataProperty property = new ODataProperty();
                        property.Name = propertyName;

                        // Lookup the property in metadata
                        IEdmProperty edmProperty    = null;
                        bool         ignoreProperty = false;
                        if (complexValueTypeReference != null)
                        {
                            edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(propertyName, complexValueTypeReference.ComplexDefinition(), this.MessageReaderSettings, out ignoreProperty);
                        }

                        if (ignoreProperty)
                        {
                            // in case of ignoreProperty = true which means to ignore undeclared property.
                            this.JsonReader.SkipValue();
                        }
                        else
                        {
                            ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                ? ODataNullValueBehaviorKind.Default
                                : this.Model.NullValueReadBehaviorKind(edmProperty);

                            // Read the property value
                            object propertyValue = this.ReadNonEntityValueImplementation(
                                edmProperty == null ? null : edmProperty.Type,
                                /*duplicatePropertyNamesChecker*/ null,
                                /*collectionValidator*/ null,
                                nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default,
                                propertyName);

                            if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.IgnoreValue || propertyValue != null)
                            {
                                duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                property.Value = propertyValue;
                                properties.Add(property);
                            }
                        }
                    }
                }
            }

            Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndObject, "After all the properties of a complex value are read the EndObject node is expected.");
            this.JsonReader.ReadEndObject();

            complexValue.Properties = new ReadOnlyEnumerable <ODataProperty>(properties);

            this.JsonReader.AssertNotBuffering();
            this.DecreaseRecursionDepth();

            return(complexValue);
        }
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                // WCF DS will skip over the rest of the complex value or entity properties if the first element in it is preceded with
                // a text node. Once the first element is found (no matter its namespace) then the non-element nodes
                // are ignored but skipped and the reading continues.
                // For ODataLib we should not do this and probably just ignore the text node even at the beginning (to be consistent).
                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                        {
                            // Found a property
                            IEdmProperty edmProperty    = null;
                            bool         isOpen         = false;
                            bool         ignoreProperty = false;

                            if (structuredType != null)
                            {
                                // Lookup the property in metadata
                                edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                {
                                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                }

                                // If the property was not declared, it must be open.
                                isOpen = edmProperty == null;
                            }

                            if (ignoreProperty)
                            {
                                this.XmlReader.Skip();
                            }
                            else
                            {
                                // EdmLib bridge marks all key properties as non-nullable, but Astoria allows them to be nullable.
                                // If the property has an annotation to ignore null values, we need to omit the property in requests.
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                        ? ODataNullValueBehaviorKind.Default
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                ODataProperty property = this.ReadProperty(
                                    false,
                                    edmProperty == null ? null : edmProperty.Name,
                                    edmProperty == null ? null : edmProperty.Type,
                                    nullValueReadBehaviorKind);
                                Debug.Assert(
                                    property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                    "If we don't ignore null values the property must not be null.");

                                if (property != null)
                                {
                                    if (isOpen)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value);
                                    }

                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                    properties.AddToSourceList(property);
                                }
                            }
                        }
                        else
                        {
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // End of the complex value.
                        break;

                    default:
                        // Non-element so for example a text node, just ignore
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
示例#11
0
        private ODataComplexValue ReadComplexValueImplementation(IEdmComplexTypeReference complexValueTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            this.IncreaseRecursionDepth();
            base.JsonReader.ReadStartObject();
            ODataComplexValue value2 = new ODataComplexValue {
                TypeName = (complexValueTypeReference != null) ? complexValueTypeReference.ODataFullName() : payloadTypeName
            };

            if (serializationTypeNameAnnotation != null)
            {
                value2.SetAnnotation <SerializationTypeNameAnnotation>(serializationTypeNameAnnotation);
            }
            if (duplicatePropertyNamesChecker == null)
            {
                duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker();
            }
            else
            {
                duplicatePropertyNamesChecker.Clear();
            }
            List <ODataProperty> sourceList = new List <ODataProperty>();
            bool flag = false;

            while (base.JsonReader.NodeType == JsonNodeType.Property)
            {
                string strB = base.JsonReader.ReadPropertyName();
                if (string.CompareOrdinal("__metadata", strB) == 0)
                {
                    if (flag)
                    {
                        throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonPropertyAndValueDeserializer_MultipleMetadataPropertiesInComplexValue);
                    }
                    flag = true;
                    base.JsonReader.SkipValue();
                }
                else if (!ValidationUtils.IsValidPropertyName(strB))
                {
                    base.JsonReader.SkipValue();
                }
                else
                {
                    ODataProperty property = new ODataProperty {
                        Name = strB
                    };
                    IEdmProperty property2      = null;
                    bool         ignoreProperty = false;
                    if (complexValueTypeReference != null)
                    {
                        property2 = ReaderValidationUtils.ValidateValuePropertyDefined(strB, complexValueTypeReference.ComplexDefinition(), base.MessageReaderSettings, out ignoreProperty);
                    }
                    if (ignoreProperty)
                    {
                        base.JsonReader.SkipValue();
                        continue;
                    }
                    ODataNullValueBehaviorKind kind = (base.ReadingResponse || (property2 == null)) ? ODataNullValueBehaviorKind.Default : base.Model.NullValueReadBehaviorKind(property2);
                    object obj2 = this.ReadNonEntityValueImplementation((property2 == null) ? null : property2.Type, null, null, kind == ODataNullValueBehaviorKind.Default);
                    if ((kind != ODataNullValueBehaviorKind.IgnoreValue) || (obj2 != null))
                    {
                        duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                        property.Value = obj2;
                        sourceList.Add(property);
                    }
                }
            }
            base.JsonReader.ReadEndObject();
            value2.Properties = new ReadOnlyEnumerable <ODataProperty>(sourceList);
            this.DecreaseRecursionDepth();
            return(value2);
        }
示例#12
0
        private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent)
        {
            ODataProperty property  = new ODataProperty();
            string        localName = base.XmlReader.LocalName;

            ValidationUtils.ValidatePropertyName(localName);
            property.Name = localName;
            object obj2 = this.ReadNonEntityValueImplementation(expectedPropertyTypeReference, null, null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent);

            if ((nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue) && (obj2 == null))
            {
                property = null;
            }
            else
            {
                property.Value = obj2;
            }
            base.XmlReader.Read();
            return(property);
        }
示例#13
0
        private IEdmProperty CreateProperty(EdmStructuredType declaringType, ResourceProperty resourceProperty)
        {
            IEdmProperty property;
            List <KeyValuePair <string, object> > annotations = (resourceProperty.CustomAnnotations == null) ? null : resourceProperty.CustomAnnotations.ToList <KeyValuePair <string, object> >();
            ODataNullValueBehaviorKind            nullValueReadBehaviorKind = ODataNullValueBehaviorKind.Default;

            if (resourceProperty.IsOfKind(ResourcePropertyKind.Primitive) || resourceProperty.IsOfKind(ResourcePropertyKind.Stream))
            {
                IEdmPrimitiveTypeReference typeReference = MetadataProviderUtils.CreatePrimitiveTypeReference(resourceProperty.ResourceType, annotations);
                if (resourceProperty.IsOfKind(ResourcePropertyKind.Key))
                {
                    if (typeReference.IsNullable)
                    {
                        typeReference = (IEdmPrimitiveTypeReference)typeReference.Clone(false);
                    }
                    nullValueReadBehaviorKind = ODataNullValueBehaviorKind.IgnoreValue;
                }
                else if (MetadataProviderUtils.ShouldDisablePrimitivePropertyNullValidation(resourceProperty, typeReference))
                {
                    nullValueReadBehaviorKind = ODataNullValueBehaviorKind.DisableValidation;
                }
                string             andRemoveDefaultValue = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations);
                EdmConcurrencyMode concurrencyMode       = resourceProperty.IsOfKind(ResourcePropertyKind.ETag) ? EdmConcurrencyMode.Fixed : EdmConcurrencyMode.None;
                property = declaringType.AddStructuralProperty(resourceProperty.Name, typeReference, andRemoveDefaultValue, concurrencyMode);
                string mimeType = resourceProperty.MimeType;
                if (!string.IsNullOrEmpty(mimeType))
                {
                    this.SetMimeType(property, mimeType);
                }
            }
            else if (resourceProperty.IsOfKind(ResourcePropertyKind.ComplexType))
            {
                IEdmTypeReference reference2   = this.EnsureTypeReference(resourceProperty.ResourceType, annotations);
                string            defaultValue = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations);
                property = declaringType.AddStructuralProperty(resourceProperty.Name, reference2, defaultValue, EdmConcurrencyMode.None);
                if (this.metadataProvider.IsV1Provider && !reference2.IsNullable)
                {
                    nullValueReadBehaviorKind = ODataNullValueBehaviorKind.DisableValidation;
                }
            }
            else if (resourceProperty.IsOfKind(ResourcePropertyKind.Collection))
            {
                string            str4       = MetadataProviderUtils.GetAndRemoveDefaultValue(annotations);
                IEdmTypeReference reference3 = this.EnsureTypeReference(resourceProperty.ResourceType, annotations);
                property = declaringType.AddStructuralProperty(resourceProperty.Name, reference3, str4, EdmConcurrencyMode.None);
            }
            else
            {
                if (!resourceProperty.IsOfKind(ResourcePropertyKind.ResourceSetReference) && !resourceProperty.IsOfKind(ResourcePropertyKind.ResourceReference))
                {
                    throw new InvalidOperationException(System.Data.Services.Strings.MetadataProviderEdmModel_UnsupportedResourcePropertyKind(resourceProperty.Kind.ToString()));
                }
                EdmEntityType     type       = (EdmEntityType)declaringType;
                IEdmTypeReference reference4 = resourceProperty.IsOfKind(ResourcePropertyKind.ResourceSetReference) ? this.EnsureEntityPrimitiveOrComplexCollectionTypeReference(resourceProperty.ResourceType, annotations) : this.EnsureTypeReference(resourceProperty.ResourceType, annotations);
                property = new MetadataProviderEdmNavigationProperty(type, resourceProperty.Name, reference4);
                type.AddProperty(property);
            }
            this.SetNullValueReaderBehavior(property, nullValueReadBehaviorKind);
            MetadataProviderUtils.ConvertCustomAnnotations(this, annotations, property);
            return(property);
        }
        /// <summary>
        /// Reads a property.
        /// </summary>
        /// <param name="expectedPropertyTypeReference">The expected type reference of the property value.</param>
        /// <param name="nullValueReadBehaviorKind">Behavior to use when reading null value for the property.</param>
        /// <param name="epmPresent">Whether any EPM mappings exist.</param>
        /// <returns>The ODataProperty representing the property in question; if null is returned from this method it means that the property is to be ignored.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element - The XML element representing the property to read.
        ///                                        Note that the method does NOT check for the property name neither it resolves the property against metadata.
        /// Post-Condition:  Any                 - The node after the property.
        /// </remarks>
        private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent)
        {
            Debug.Assert(
                expectedPropertyTypeReference == null || expectedPropertyTypeReference.IsODataPrimitiveTypeKind() ||
                expectedPropertyTypeReference.IsODataComplexTypeKind() || expectedPropertyTypeReference.IsNonEntityODataCollectionTypeKind(),
                "Only primitive, complex and collection types can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element);
            Debug.Assert(this.UseServerFormatBehavior || this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace), "Property elements must be in the OData namespace (unless we are running in WCF DS server format mode).");
            this.XmlReader.AssertNotBuffering();

            ODataProperty property = new ODataProperty();
            string propertyName = this.XmlReader.LocalName;
            ValidationUtils.ValidatePropertyName(propertyName);
            property.Name = propertyName;

            object propertyValue = this.ReadNonEntityValueImplementation(
                expectedPropertyTypeReference, 
                /*duplicatePropertyNamesChecker*/ null, 
                /*collectionValidator*/ null,
                nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, 
                epmPresent);

            if (nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue && propertyValue == null)
            {
                property = null;
            }
            else
            {
                property.Value = propertyValue;
            }

            // Read past the end tag of the property or the start tag if the element is empty.
            this.XmlReader.Read();

            this.XmlReader.AssertNotBuffering();
            return property;
        }
 private ODataProperty ReadProperty(IEdmTypeReference expectedPropertyTypeReference, ODataNullValueBehaviorKind nullValueReadBehaviorKind, bool epmPresent)
 {
     ODataProperty property = new ODataProperty();
     string localName = base.XmlReader.LocalName;
     ValidationUtils.ValidatePropertyName(localName);
     property.Name = localName;
     object obj2 = this.ReadNonEntityValueImplementation(expectedPropertyTypeReference, null, null, nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default, epmPresent);
     if ((nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue) && (obj2 == null))
     {
         property = null;
     }
     else
     {
         property.Value = obj2;
     }
     base.XmlReader.Read();
     return property;
 }