Esempio n. 1
0
        private void ReadOpenProperty(IODataJsonReaderEntryState entryState, string propertyName)
        {
            object obj2 = base.ReadNonEntityValue(null, null, null, true);

            ValidationUtils.ValidateOpenPropertyValue(propertyName, obj2);
            AddEntryProperty(entryState, propertyName, obj2);
        }
Esempio n. 2
0
        private ODataNavigationLink ReadUndeclaredProperty(IODataJsonReaderEntryState entryState, string propertyName)
        {
            bool flag  = false;
            bool flag2 = false;

            if (base.JsonReader.NodeType == JsonNodeType.StartObject)
            {
                base.JsonReader.StartBuffering();
                base.JsonReader.Read();
                if (base.JsonReader.NodeType == JsonNodeType.Property)
                {
                    string strA = base.JsonReader.ReadPropertyName();
                    if (string.CompareOrdinal(strA, "__deferred") == 0)
                    {
                        flag2 = true;
                    }
                    else if (string.CompareOrdinal(strA, "__mediaresource") == 0)
                    {
                        flag = true;
                    }
                    base.JsonReader.SkipValue();
                    if (base.JsonReader.NodeType != JsonNodeType.EndObject)
                    {
                        flag  = false;
                        flag2 = false;
                    }
                }
                base.JsonReader.StopBuffering();
            }
            if (flag || flag2)
            {
                if (!base.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.ReportUndeclaredLinkProperty))
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
                }
            }
            else if (!base.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty))
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
            }
            if (flag2)
            {
                ODataNavigationLink navigationLink = new ODataNavigationLink {
                    Name         = propertyName,
                    IsCollection = null
                };
                entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
                return(navigationLink);
            }
            if (flag)
            {
                object propertyValue = this.ReadStreamPropertyValue();
                AddEntryProperty(entryState, propertyName, propertyValue);
                return(null);
            }
            base.JsonReader.SkipValue();
            return(null);
        }
 private static void AddEntryProperty(IODataJsonReaderEntryState entryState, string propertyName, object propertyValue)
 {
     ODataProperty property = new ODataProperty {
         Name = propertyName,
         Value = propertyValue
     };
     entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
     ReaderUtils.AddPropertyToPropertiesList(entryState.Entry.Properties, property);
 }
Esempio n. 4
0
        private static void AddEntryProperty(IODataJsonReaderEntryState entryState, string propertyName, object propertyValue)
        {
            ODataProperty property = new ODataProperty {
                Name  = propertyName,
                Value = propertyValue
            };

            entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
            ReaderUtils.AddPropertyToPropertiesList(entryState.Entry.Properties, property);
        }
Esempio n. 5
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);
            }
        }
Esempio n. 6
0
        protected override bool ReadAtNavigationLinkStartImplementation()
        {
            ODataNavigationLink        currentNavigationLink = base.CurrentNavigationLink;
            IODataJsonReaderEntryState linkParentEntityScope = (IODataJsonReaderEntryState)base.LinkParentEntityScope;

            if (this.jsonInputContext.ReadingResponse && this.jsonEntryAndFeedDeserializer.IsDeferredLink(true))
            {
                linkParentEntityScope.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(currentNavigationLink, false, currentNavigationLink.IsCollection);
                this.jsonEntryAndFeedDeserializer.ReadDeferredNavigationLink(currentNavigationLink);
                this.ReplaceScope(ODataReaderState.NavigationLinkEnd);
            }
            else if (!currentNavigationLink.IsCollection.Value)
            {
                if (!this.jsonInputContext.ReadingResponse && this.jsonEntryAndFeedDeserializer.IsEntityReferenceLink())
                {
                    linkParentEntityScope.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(currentNavigationLink, false, false);
                    ODataEntityReferenceLink item = this.jsonEntryAndFeedDeserializer.ReadEntityReferenceLink();
                    this.EnterScope(ODataReaderState.EntityReferenceLink, item, null);
                }
                else
                {
                    linkParentEntityScope.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(currentNavigationLink, true, false);
                    if (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.PrimitiveValue)
                    {
                        this.EnterScope(ODataReaderState.EntryStart, null, base.CurrentEntityType);
                    }
                    else
                    {
                        this.ReadEntryStart();
                    }
                }
            }
            else
            {
                linkParentEntityScope.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(currentNavigationLink, true, true);
                if (this.jsonInputContext.ReadingResponse)
                {
                    this.ReadFeedStart(true);
                }
                else
                {
                    if ((this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartObject) && (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartArray))
                    {
                        throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonReader_CannotReadFeedStart(this.jsonEntryAndFeedDeserializer.JsonReader.NodeType));
                    }
                    bool isResultsWrapperExpected = this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.StartObject;
                    this.jsonEntryAndFeedDeserializer.ReadFeedStart(new ODataFeed(), isResultsWrapperExpected, true);
                    this.CurrentJsonScope.FeedHasResultsWrapper = isResultsWrapperExpected;
                    this.ReadExpandedCollectionNavigationLinkContentInRequest();
                }
            }
            return(true);
        }
Esempio n. 7
0
        internal void ValidateEntryMetadata(IODataJsonReaderEntryState entryState)
        {
            ODataEntry     entry      = entryState.Entry;
            IEdmEntityType entityType = entryState.EntityType;

            if (base.Model.HasDefaultStream(entityType) && (entry.MediaResource == null))
            {
                ODataStreamReferenceValue instance = null;
                ODataJsonReaderUtils.EnsureInstance <ODataStreamReferenceValue>(ref instance);
                entry.MediaResource = instance;
            }
            bool useDefaultFormatBehavior = base.UseDefaultFormatBehavior;

            ValidationUtils.ValidateEntryMetadata(entry, entityType, base.Model, useDefaultFormatBehavior);
        }
Esempio n. 8
0
 private void ReadPropertiesMetadataProperty(IODataJsonReaderEntryState entryState, ref ODataJsonReaderUtils.MetadataPropertyBitMask metadataPropertiesFoundBitField)
 {
     if (!base.ReadingResponse || (base.MessageReaderSettings.MaxProtocolVersion < ODataVersion.V3))
     {
         base.JsonReader.SkipValue();
     }
     else
     {
         ODataJsonReaderUtils.VerifyMetadataPropertyNotFound(ref metadataPropertiesFoundBitField, ODataJsonReaderUtils.MetadataPropertyBitMask.Properties, "properties");
         if (base.JsonReader.NodeType != JsonNodeType.StartObject)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonEntryAndFeedDeserializer_PropertyInEntryMustHaveObjectValue("properties", base.JsonReader.NodeType));
         }
         base.JsonReader.ReadStartObject();
         while (base.JsonReader.NodeType == JsonNodeType.Property)
         {
             string associationLinkName = base.JsonReader.ReadPropertyName();
             ValidationUtils.ValidateAssociationLinkName(associationLinkName);
             ReaderValidationUtils.ValidateNavigationPropertyDefined(associationLinkName, entryState.EntityType, base.MessageReaderSettings);
             base.JsonReader.ReadStartObject();
             while (base.JsonReader.NodeType == JsonNodeType.Property)
             {
                 if (string.CompareOrdinal(base.JsonReader.ReadPropertyName(), "associationuri") == 0)
                 {
                     string propertyValue = base.JsonReader.ReadStringValue("associationuri");
                     ODataJsonReaderUtils.ValidateMetadataStringProperty(propertyValue, "associationuri");
                     ODataAssociationLink associationLink = new ODataAssociationLink {
                         Name = associationLinkName,
                         Url  = base.ProcessUriFromPayload(propertyValue)
                     };
                     ValidationUtils.ValidateAssociationLink(associationLink);
                     entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(associationLink);
                     ReaderUtils.AddAssociationLinkToEntry(entryState.Entry, associationLink);
                 }
                 else
                 {
                     base.JsonReader.SkipValue();
                 }
             }
             base.JsonReader.ReadEndObject();
         }
         base.JsonReader.ReadEndObject();
     }
 }
        /// <summary>
        /// Read an entry-level property and check its version compliance. 
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <param name="edmProperty">The EDM property of the property being read, or null if the property is an open property.</param>
        /// <remarks>
        /// Pre-Condition:  The reader is positioned on the first node of the property value
        /// Post-Condition: JsonNodeType.Property:    the next property of the entry
        ///                 JsonNodeType.EndObject:   the end-object node of the entry
        /// </remarks>
        private void ReadEntryProperty(IODataJsonReaderEntryState entryState, IEdmProperty edmProperty)
        {
            Debug.Assert(entryState != null, "entryState != null");
            Debug.Assert(edmProperty != null, "edmProperty != null");
            this.JsonReader.AssertNotBuffering();

            ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse
                ? ODataNullValueBehaviorKind.Default
                : this.Model.NullValueReadBehaviorKind(edmProperty);
            IEdmTypeReference propertyTypeReference = edmProperty.Type;
            object propertyValue = propertyTypeReference.IsStream()
                ? this.ReadStreamPropertyValue()
                : this.ReadNonEntityValue(
                    propertyTypeReference, 
                    /*duplicatePropertyNamesChecker*/ null, 
                    /*collectionValidator*/ null, 
                    nullValueReadBehaviorKind == ODataNullValueBehaviorKind.Default);

            if (nullValueReadBehaviorKind != ODataNullValueBehaviorKind.IgnoreValue || propertyValue != null)
            {
                AddEntryProperty(entryState, edmProperty.Name, propertyValue);
            }

            this.JsonReader.AssertNotBuffering();
            Debug.Assert(
                this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                "Post-Condition: expected JsonNodeType.Property or JsonNodeType.EndObject");
        }
        /// <summary>
        /// Read an open property.
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <param name="propertyName">The name of the open property to read.</param>
        /// <remarks>
        /// Pre-Condition:  The reader is positioned on the first node of the property value
        /// Post-Condition: JsonNodeType.Property:    the next property of the entry
        ///                 JsonNodeType.EndObject:   the end-object node of the entry
        /// </remarks>
        private void ReadOpenProperty(IODataJsonReaderEntryState entryState, string propertyName)
        {
            Debug.Assert(entryState != null, "entryState != null");
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");
            this.JsonReader.AssertNotBuffering();

            object propertyValue = this.ReadNonEntityValue(
                /*expectedValueTypeReference*/ null, 
                /*duplicatePropertyNamesChecker*/ null, 
                /*collectionValidator*/ null,
                /*validateNullValue*/ true);

            ValidationUtils.ValidateOpenPropertyValue(propertyName, propertyValue);
            AddEntryProperty(entryState, propertyName, propertyValue);

            this.JsonReader.AssertNotBuffering();
            Debug.Assert(
                this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                "Post-Condition: expected JsonNodeType.Property or JsonNodeType.EndObject");
        }
        /// <summary>
        /// Reads the content of an entry until a navigation link is detected.
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <param name="navigationProperty">If a navigation link was found this parameter will hold the navigation property for that link, otherwise it's null.</param>
        /// <returns>A <see cref="ODataNavigationLink"/> instance representing the navigation link detected while reading the entry contents; null if no navigation link was detected.</returns>
        /// <remarks>
        /// Pre-Condition:  JsonNodeType.Property               The property to read
        ///                 JsonNodeType.EndObject              If no (more) properties exist in the entry's content
        /// Post-Condition: JsonNodeType.EndObject              If no (more) properties exist in the entry's content
        ///                 JsonNodeType.StartObject            The first node of the navigation link property value to read next 
        ///                                                     (deferred link or entry inside expanded link or feed with 'results' wrapper inside expanded link)
        ///                 JsonNodeType.StartArray             feed without 'results' wrapper inside of expanded link
        ///                 JsonNodeType.PrimitiveValue (null)  Expanded null entry
        /// </remarks>
        internal ODataNavigationLink ReadEntryContent(
            IODataJsonReaderEntryState entryState,
            out IEdmNavigationProperty navigationProperty)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entryState != null, "entryState != null");
            Debug.Assert(entryState.EntityType != null && this.Model.IsUserModel(), "A non-null entity type and non-null model are required.");
            Debug.Assert(
                this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                "Pre-Condition: JsonNodeType.Property or JsonNodeType.EndObject");
            this.JsonReader.AssertNotBuffering();

            ODataNavigationLink navigationLink = null;
            navigationProperty = null;
            IEdmEntityType entityType = entryState.EntityType;
            Debug.Assert(entityType != null, "In JSON we must always have an entity type when reading entity.");

            // figure out whether we have more properties for this entry
            // read all the properties until we hit a link
            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();

                // check the well-known property names first
                if (string.CompareOrdinal(JsonConstants.ODataMetadataName, propertyName) == 0)
                {
                    // __metadata property
                    if (entryState.MetadataPropertyFound)
                    {
                        throw new ODataException(o.Strings.ODataJsonEntryAndFeedDeserializer_MultipleMetadataPropertiesInEntryValue);
                    }

                    entryState.MetadataPropertyFound = true;

                    // Just skip over the value since we should have already scanned ahead for it by now.
                    this.JsonReader.SkipValue();
                }
                else
                {
                    if (!ValidationUtils.IsValidPropertyName(propertyName))
                    {
                        this.JsonReader.SkipValue();
                        continue;
                    }

                    IEdmProperty edmProperty = ReaderValidationUtils.FindDefinedProperty(propertyName, entityType, this.MessageReaderSettings);
                    if (edmProperty != null)
                    {
                        // Declared property - read it.
                        navigationProperty = edmProperty as IEdmNavigationProperty;
                        if (navigationProperty != null)
                        {
                            if (this.ShouldEntryPropertyBeSkipped())
                            {
                                this.JsonReader.SkipValue();
                            }
                            else
                            {
                                // this can be a deferred link or an expanded link (with entry or feed payload)
                                bool isCollection = navigationProperty.Type.IsCollection();
                                navigationLink = new ODataNavigationLink
                                {
                                    Name = propertyName,
                                    IsCollection = isCollection
                                };

                                this.ValidateNavigationLinkPropertyValue(isCollection);
                                entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
                            }
                        }
                        else
                        {
                            // NOTE: we currently do not check whether the property should be skipped
                            //       here because this can only happen for navigation properties and open properties.
                            this.ReadEntryProperty(entryState, edmProperty);
                        }
                    }
                    else
                    {
                        if (entityType.IsOpen)
                        {
                            if (this.ShouldEntryPropertyBeSkipped())
                            {
                                this.JsonReader.SkipValue();
                            }
                            else
                            {
                                // Open property - read it as such.
                                this.ReadOpenProperty(entryState, propertyName);
                            }
                        }
                        else
                        {
                            // Undeclared property on a non-open type - we need to run detection alogorithm here.
                            navigationLink = this.ReadUndeclaredProperty(entryState, propertyName);

                            // Note that if navigation link is returned it's already validated, so we just report it here.
                        }
                    }
                }

                if (navigationLink != null)
                {
                    // we found a navigation link
                    // stop parsing the entry content and return to the caller
                    break;
                }

                Debug.Assert(
                    this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                    "After reading a property the reader should be positioned on another property or have hit the end of the object.");
            }

            this.JsonReader.AssertNotBuffering();

            // The reader can be either on
            //  - StartObject - if it's an expanded entry, or expanded feed wrapped with 'results' wrapper
            //  - StartArray - if it's an expanded feed that is not wrapped with 'results' wrapper
            //  - PrimitiveValue (null) - if it's an expanded null entry
            //  - EndObject - end of the entry
            Debug.Assert(
                navigationLink != null && this.JsonReader.NodeType == JsonNodeType.StartObject ||
                navigationLink != null && this.JsonReader.NodeType == JsonNodeType.StartArray ||
                navigationLink != null && this.JsonReader.NodeType == JsonNodeType.PrimitiveValue && this.JsonReader.Value == null ||
                this.JsonReader.NodeType == JsonNodeType.EndObject,
                "Post-Condition: expected JsonNodeType.StartObject or JsonNodeType.StartArray or JsonNodeType.EndObject or JsonNodeType.Primitive (with null value)");

            return navigationLink;
        }
        /// <summary>
        /// Adds a new property to an entry.
        /// </summary>
        /// <param name="entryState">The entry state for the entry to add the property to.</param>
        /// <param name="propertyName">The name of the property to add.</param>
        /// <param name="propertyValue">The value of the property to add.</param>
        private static void AddEntryProperty(IODataJsonReaderEntryState entryState, string propertyName, object propertyValue)
        {
            Debug.Assert(entryState != null, "entryState != null");
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            ODataProperty property = new ODataProperty { Name = propertyName, Value = propertyValue };
            entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);

            ReaderUtils.AddPropertyToPropertiesList(entryState.Entry.Properties, property);
        }
        /// <summary>
        /// Reads the entry metadata property.
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <remarks>
        /// This method does not move the reader.
        /// Pre-Condition:  JsonNodeType.Object             The start object of the __metadata property value.
        /// Post-Condition: JsonNodeType.EndObject          The end object of the __metadtaa property value.
        /// </remarks>
        internal void ReadEntryMetadataPropertyValue(IODataJsonReaderEntryState entryState)
        {
            DebugUtils.CheckNoExternalCallers();
            this.AssertJsonCondition(JsonNodeType.StartObject);
            this.JsonReader.AssertBuffering();

            ODataEntry entry = entryState.Entry;

            // read over the start-object node
            this.JsonReader.ReadStartObject();

            ODataStreamReferenceValue mediaResource = null;
            ODataJsonReaderUtils.MetadataPropertyBitMask metadataPropertiesFoundBitField = 0;
            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();
                switch (propertyName)
                {
                    case JsonConstants.ODataMetadataUriName:    // 'uri'
                        this.ReadUriMetadataProperty(entry, ref metadataPropertiesFoundBitField);
                        break;

                    case JsonConstants.ODataEntryIdName:   // 'id'
                        this.ReadIdMetadataProperty(entry, ref metadataPropertiesFoundBitField);
                        break;

                    case JsonConstants.ODataMetadataETagName:   // 'etag'
                        this.ReadETagMetadataProperty(entry, ref metadataPropertiesFoundBitField);
                        break;

                    case JsonConstants.ODataMetadataTypeName:   // 'type'
                        // The type was already read and validated.
                        this.JsonReader.SkipValue();
                        break;

                    case JsonConstants.ODataMetadataMediaUriName:   // 'media_src'
                        this.ReadMediaSourceMetadataProperty(ref metadataPropertiesFoundBitField, ref mediaResource);
                        break;

                    case JsonConstants.ODataMetadataEditMediaName:  // 'edit_media'
                        this.ReadEditMediaMetadataProperty(ref metadataPropertiesFoundBitField, ref mediaResource);
                        break;

                    case JsonConstants.ODataMetadataContentTypeName:  // 'content_type'
                        this.ReadContentTypeMetadataProperty(ref metadataPropertiesFoundBitField, ref mediaResource);
                        break;

                    case JsonConstants.ODataMetadataMediaETagName:  // 'media_etag'
                        this.ReadMediaETagMetadataProperty(ref metadataPropertiesFoundBitField, ref mediaResource);
                        break;

                    case JsonConstants.ODataActionsMetadataName:  // 'actions'
                        this.ReadActionsMetadataProperty(entry, ref metadataPropertiesFoundBitField);
                        break;

                    case JsonConstants.ODataFunctionsMetadataName:  // 'functions'
                        this.ReadFunctionsMetadataProperty(entry, ref metadataPropertiesFoundBitField);
                        break;

                    case JsonConstants.ODataMetadataPropertiesName:  // 'properties'
                        this.ReadPropertiesMetadataProperty(entryState, ref metadataPropertiesFoundBitField);
                        break;

                    default:
                        // ignore all extra properties in __metadata that we don't understand
                        this.JsonReader.SkipValue();
                        break;
                }
            }

            entry.MediaResource = mediaResource;

            this.AssertJsonCondition(JsonNodeType.EndObject);
        }
        /// <summary>
        /// Validates entry metadata properties against the model.
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <remarks>
        /// This method must be called only after the ReadEntryMetadata was already called.
        /// It should be called always, regardless of whether the __metadata property was found ot not.
        /// </remarks>
        internal void ValidateEntryMetadata(IODataJsonReaderEntryState entryState)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entryState != null, "entryState != null");

            ODataEntry entry = entryState.Entry; 
            IEdmEntityType entityType = entryState.EntityType;
            Debug.Assert(entityType != null, "We should have resolved the entity type by now.");

            if (this.Model.HasDefaultStream(entityType) && entry.MediaResource == null)
            {
                ODataStreamReferenceValue mediaResource = null; 
                ODataJsonReaderUtils.EnsureInstance(ref mediaResource);
                entry.MediaResource = mediaResource;
            }

            // By default validate the media resource.
            // In WCF DS Server mode, do not validate in JSON (here).
            // In WCF DS Client mode, do not validate.
            bool validateMediaResource = this.UseDefaultFormatBehavior;
            ValidationUtils.ValidateEntryMetadata(entry, entityType, this.Model, validateMediaResource);
        }
 private void ReadPropertiesMetadataProperty(IODataJsonReaderEntryState entryState, ref ODataJsonReaderUtils.MetadataPropertyBitMask metadataPropertiesFoundBitField)
 {
     if (!base.ReadingResponse || (base.MessageReaderSettings.MaxProtocolVersion < ODataVersion.V3))
     {
         base.JsonReader.SkipValue();
     }
     else
     {
         ODataJsonReaderUtils.VerifyMetadataPropertyNotFound(ref metadataPropertiesFoundBitField, ODataJsonReaderUtils.MetadataPropertyBitMask.Properties, "properties");
         if (base.JsonReader.NodeType != JsonNodeType.StartObject)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonEntryAndFeedDeserializer_PropertyInEntryMustHaveObjectValue("properties", base.JsonReader.NodeType));
         }
         base.JsonReader.ReadStartObject();
         while (base.JsonReader.NodeType == JsonNodeType.Property)
         {
             string associationLinkName = base.JsonReader.ReadPropertyName();
             ValidationUtils.ValidateAssociationLinkName(associationLinkName);
             ReaderValidationUtils.ValidateNavigationPropertyDefined(associationLinkName, entryState.EntityType, base.MessageReaderSettings);
             base.JsonReader.ReadStartObject();
             while (base.JsonReader.NodeType == JsonNodeType.Property)
             {
                 if (string.CompareOrdinal(base.JsonReader.ReadPropertyName(), "associationuri") == 0)
                 {
                     string propertyValue = base.JsonReader.ReadStringValue("associationuri");
                     ODataJsonReaderUtils.ValidateMetadataStringProperty(propertyValue, "associationuri");
                     ODataAssociationLink associationLink = new ODataAssociationLink {
                         Name = associationLinkName,
                         Url = base.ProcessUriFromPayload(propertyValue)
                     };
                     ValidationUtils.ValidateAssociationLink(associationLink);
                     entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(associationLink);
                     ReaderUtils.AddAssociationLinkToEntry(entryState.Entry, associationLink);
                 }
                 else
                 {
                     base.JsonReader.SkipValue();
                 }
             }
             base.JsonReader.ReadEndObject();
         }
         base.JsonReader.ReadEndObject();
     }
 }
        /// <summary>
        /// Read the property metadata for the properties of an entry being read.
        /// </summary>
        /// <param name="entryState">The entry state for the current reader.</param>
        /// <param name="metadataPropertiesFoundBitField">The bit fields with all the properties found in metadata value so far.</param>
        /// <remarks>
        /// Pre-Condition:  first node of the 'properties' property's value (we will throw if this is not a start object node)
        /// Post-Condition: JsonNodeType.Property:      the next metadata property
        ///                 JsonNodeType.EndObject:     the end-object node of the metadata object
        ///                 
        /// This method will not validate anything against the model because it will read the type name and thus it can't rely
        /// on knowing the actual type of the entry being read.
        /// </remarks>
        private void ReadPropertiesMetadataProperty(
            IODataJsonReaderEntryState entryState,
            ref ODataJsonReaderUtils.MetadataPropertyBitMask metadataPropertiesFoundBitField)
        {
            Debug.Assert(entryState != null, "entryState != null");

            if (!this.ReadingResponse || this.MessageReaderSettings.MaxProtocolVersion < ODataVersion.V3)
            {
                this.JsonReader.SkipValue();
                return;
            }

            ODataJsonReaderUtils.VerifyMetadataPropertyNotFound(
                ref metadataPropertiesFoundBitField,
                ODataJsonReaderUtils.MetadataPropertyBitMask.Properties,
                JsonConstants.ODataMetadataPropertiesName);

            this.JsonReader.AssertBuffering();

            // make sure the 'properties' property value is an object
            if (this.JsonReader.NodeType != JsonNodeType.StartObject)
            {
                throw new ODataException(o.Strings.ODataJsonEntryAndFeedDeserializer_PropertyInEntryMustHaveObjectValue(JsonConstants.ODataMetadataPropertiesName, this.JsonReader.NodeType));
            }

            // read over the start-object node of the metadata object for 'properties'
            this.JsonReader.ReadStartObject();

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();

                ValidationUtils.ValidateAssociationLinkName(propertyName);
                ReaderValidationUtils.ValidateNavigationPropertyDefined(propertyName, entryState.EntityType, this.MessageReaderSettings);

                // read the start-object node of the metadata for the current propertyName
                this.JsonReader.ReadStartObject();

                while (this.JsonReader.NodeType == JsonNodeType.Property)
                {
                    string innerPropertyName = this.JsonReader.ReadPropertyName();

                    // ignore all properties we don't understand
                    if (string.CompareOrdinal(innerPropertyName, JsonConstants.ODataMetadataPropertiesAssociationUriName) == 0)
                    {
                        string associationUrlString = this.JsonReader.ReadStringValue(JsonConstants.ODataMetadataPropertiesAssociationUriName);
                        ODataJsonReaderUtils.ValidateMetadataStringProperty(associationUrlString, JsonConstants.ODataMetadataPropertiesAssociationUriName);
                        ODataAssociationLink associationLink = new ODataAssociationLink
                        {
                            Name = propertyName,
                            Url = this.ProcessUriFromPayload(associationUrlString)
                        };

                        ValidationUtils.ValidateAssociationLink(associationLink);
                        entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(associationLink);
                        ReaderUtils.AddAssociationLinkToEntry(entryState.Entry, associationLink);
                    }
                    else
                    {
                        // skip over all unknown properties and read the next property or 
                        // the end of the metadata for the current propertyName
                        this.JsonReader.SkipValue();
                    }
                }

                // read the end-object node of the metadata for the current propertyName
                this.JsonReader.ReadEndObject();
            }

            // read over the end-object node of the metadata object for 'properties'
            this.JsonReader.ReadEndObject();

            this.JsonReader.AssertBuffering();
            Debug.Assert(
                this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                "Post-Condition: expected JsonNodeType.Property or JsonNodeType.EndObject");
        }
        /// <summary>
        /// Read an undeclared property. That is a property which is not declared by the model, but the owning type is not an open type.
        /// </summary>
        /// <param name="entryState">The state of the reader for entry to read.</param>
        /// <param name="propertyName">The name of the open property to read.</param>
        /// <remarks>
        /// Pre-Condition:  The reader is positioned on the first node of the property value
        /// Post-Condition: JsonNodeType.Property:    the next property of the entry
        ///                 JsonNodeType.EndObject:   the end-object node of the entry
        /// </remarks>
        /// <returns>A navigation link instance if the propery read is a navigation link which should be reported to the caller.
        /// Otherwise null if the property was either ignored or read and added to the list of properties on the entry.</returns>
        private ODataNavigationLink ReadUndeclaredProperty(IODataJsonReaderEntryState entryState, string propertyName)
        {
            Debug.Assert(entryState != null, "entryState != null");
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            // Undeclared property
            // Detect whether it's a link property or value property.
            // Link properties are stream properties and deferred links.
            bool streamPropertyFound = false;
            bool deferredLinkFound = false;
            if (this.JsonReader.NodeType == JsonNodeType.StartObject)
            {
                this.JsonReader.StartBuffering();

                // Both stream property and deferred link must be an object with exactly one property in it, with the right name.
                this.JsonReader.Read();
                if (this.JsonReader.NodeType == JsonNodeType.Property)
                {
                    string innerPropertyName = this.JsonReader.ReadPropertyName();
                    if (string.CompareOrdinal(innerPropertyName, JsonConstants.ODataDeferredName) == 0)
                    {
                        deferredLinkFound = true;
                    }
                    else if (string.CompareOrdinal(innerPropertyName, JsonConstants.ODataMetadataMediaResourceName) == 0)
                    {
                        streamPropertyFound = true;
                    }

                    this.JsonReader.SkipValue();

                    // The __mediaresource or __deferred is not the only property, so the value is not a stream property or deferred link.
                    if (this.JsonReader.NodeType != JsonNodeType.EndObject)
                    {
                        streamPropertyFound = false;
                        deferredLinkFound = false;
                    }
                }

                this.JsonReader.StopBuffering();
            }

            if (streamPropertyFound || deferredLinkFound)
            {
                // Undeclared link properties (stream property or deferred links) are reported if the right flag is used, otherwise we need to fail
                // reporting the undeclared property.
                if (!this.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.ReportUndeclaredLinkProperty))
                {
                    throw new ODataException(o.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
                }
            }
            else
            {
                // Undeclared value properties (anything which doesn't look like stream property or deferred link) are ignored if the right flag is used,
                // otherwise we need to fail reporting the undeclared property.
                if (!this.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty))
                {
                    throw new ODataException(o.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
                }
            }

            if (deferredLinkFound)
            {
                // We've found a deferred link - so report it (we've already checked the flags which allow this).
                ODataNavigationLink navigationLink = new ODataNavigationLink
                {
                    Name = propertyName,
                    IsCollection = null
                };

                // Note - no need to validate the navigation link since we know it's a valid deferred link at least from the first object content.
                entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
                return navigationLink;
            }

            if (streamPropertyFound)
            {
                // We've found a stream property, so read it and report it (we've already checked the flags which allow this).
                object propertyValue = this.ReadStreamPropertyValue();
                AddEntryProperty(entryState, propertyName, propertyValue);
                return null;
            }

            // Primitive, Complex, Collection or expanded link property, or property we don't recognize - treat all of these as value properties
            // and thus ignore them.
            // Note that in JSON expanded navigation links don't have the URL of the navigation link (the "href")
            // and thus we would have nothing to report even if the ReportUndeclaredLinkProperty would be set to true.
            // As such it's OK to treat them as value properties all up.
            this.JsonReader.SkipValue();
            return null;
        }
 private void ReadOpenProperty(IODataJsonReaderEntryState entryState, string propertyName)
 {
     object obj2 = base.ReadNonEntityValue(null, null, null, true);
     ValidationUtils.ValidateOpenPropertyValue(propertyName, obj2);
     AddEntryProperty(entryState, propertyName, obj2);
 }
 internal ODataNavigationLink ReadEntryContent(IODataJsonReaderEntryState entryState, out IEdmNavigationProperty navigationProperty)
 {
     ODataNavigationLink navigationLink = null;
     navigationProperty = null;
     IEdmEntityType entityType = entryState.EntityType;
     while (base.JsonReader.NodeType == JsonNodeType.Property)
     {
         string strB = base.JsonReader.ReadPropertyName();
         if (string.CompareOrdinal("__metadata", strB) == 0)
         {
             if (entryState.MetadataPropertyFound)
             {
                 throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonEntryAndFeedDeserializer_MultipleMetadataPropertiesInEntryValue);
             }
             entryState.MetadataPropertyFound = true;
             base.JsonReader.SkipValue();
         }
         else
         {
             if (!ValidationUtils.IsValidPropertyName(strB))
             {
                 base.JsonReader.SkipValue();
                 continue;
             }
             IEdmProperty edmProperty = ReaderValidationUtils.FindDefinedProperty(strB, entityType, base.MessageReaderSettings);
             if (edmProperty != null)
             {
                 navigationProperty = edmProperty as IEdmNavigationProperty;
                 if (navigationProperty != null)
                 {
                     if (this.ShouldEntryPropertyBeSkipped())
                     {
                         base.JsonReader.SkipValue();
                     }
                     else
                     {
                         bool flag = navigationProperty.Type.IsCollection();
                         navigationLink = new ODataNavigationLink {
                             Name = strB,
                             IsCollection = new bool?(flag)
                         };
                         this.ValidateNavigationLinkPropertyValue(flag);
                         entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
                     }
                 }
                 else
                 {
                     this.ReadEntryProperty(entryState, edmProperty);
                 }
             }
             else if (entityType.IsOpen)
             {
                 if (this.ShouldEntryPropertyBeSkipped())
                 {
                     base.JsonReader.SkipValue();
                 }
                 else
                 {
                     this.ReadOpenProperty(entryState, strB);
                 }
             }
             else
             {
                 navigationLink = this.ReadUndeclaredProperty(entryState, strB);
             }
         }
         if (navigationLink != null)
         {
             return navigationLink;
         }
     }
     return navigationLink;
 }
 private ODataNavigationLink ReadUndeclaredProperty(IODataJsonReaderEntryState entryState, string propertyName)
 {
     bool flag = false;
     bool flag2 = false;
     if (base.JsonReader.NodeType == JsonNodeType.StartObject)
     {
         base.JsonReader.StartBuffering();
         base.JsonReader.Read();
         if (base.JsonReader.NodeType == JsonNodeType.Property)
         {
             string strA = base.JsonReader.ReadPropertyName();
             if (string.CompareOrdinal(strA, "__deferred") == 0)
             {
                 flag2 = true;
             }
             else if (string.CompareOrdinal(strA, "__mediaresource") == 0)
             {
                 flag = true;
             }
             base.JsonReader.SkipValue();
             if (base.JsonReader.NodeType != JsonNodeType.EndObject)
             {
                 flag = false;
                 flag2 = false;
             }
         }
         base.JsonReader.StopBuffering();
     }
     if (flag || flag2)
     {
         if (!base.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.ReportUndeclaredLinkProperty))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
         }
     }
     else if (!base.MessageReaderSettings.UndeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, entryState.EntityType.ODataFullName()));
     }
     if (flag2)
     {
         ODataNavigationLink navigationLink = new ODataNavigationLink {
             Name = propertyName,
             IsCollection = null
         };
         entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
         return navigationLink;
     }
     if (flag)
     {
         object propertyValue = this.ReadStreamPropertyValue();
         AddEntryProperty(entryState, propertyName, propertyValue);
         return null;
     }
     base.JsonReader.SkipValue();
     return null;
 }
Esempio n. 21
0
        internal void ReadEntryMetadataPropertyValue(IODataJsonReaderEntryState entryState)
        {
            ODataEntry entry = entryState.Entry;

            base.JsonReader.ReadStartObject();
            ODataStreamReferenceValue mediaResource = null;

            ODataJsonReaderUtils.MetadataPropertyBitMask none = ODataJsonReaderUtils.MetadataPropertyBitMask.None;
            while (base.JsonReader.NodeType == JsonNodeType.Property)
            {
                switch (base.JsonReader.ReadPropertyName())
                {
                case "uri":
                {
                    this.ReadUriMetadataProperty(entry, ref none);
                    continue;
                }

                case "id":
                {
                    this.ReadIdMetadataProperty(entry, ref none);
                    continue;
                }

                case "etag":
                {
                    this.ReadETagMetadataProperty(entry, ref none);
                    continue;
                }

                case "type":
                {
                    base.JsonReader.SkipValue();
                    continue;
                }

                case "media_src":
                {
                    this.ReadMediaSourceMetadataProperty(ref none, ref mediaResource);
                    continue;
                }

                case "edit_media":
                {
                    this.ReadEditMediaMetadataProperty(ref none, ref mediaResource);
                    continue;
                }

                case "content_type":
                {
                    this.ReadContentTypeMetadataProperty(ref none, ref mediaResource);
                    continue;
                }

                case "media_etag":
                {
                    this.ReadMediaETagMetadataProperty(ref none, ref mediaResource);
                    continue;
                }

                case "actions":
                {
                    this.ReadActionsMetadataProperty(entry, ref none);
                    continue;
                }

                case "functions":
                {
                    this.ReadFunctionsMetadataProperty(entry, ref none);
                    continue;
                }

                case "properties":
                {
                    this.ReadPropertiesMetadataProperty(entryState, ref none);
                    continue;
                }
                }
                base.JsonReader.SkipValue();
            }
            entry.MediaResource = mediaResource;
        }
Esempio n. 22
0
        internal ODataNavigationLink ReadEntryContent(IODataJsonReaderEntryState entryState, out IEdmNavigationProperty navigationProperty)
        {
            ODataNavigationLink navigationLink = null;

            navigationProperty = null;
            IEdmEntityType entityType = entryState.EntityType;

            while (base.JsonReader.NodeType == JsonNodeType.Property)
            {
                string strB = base.JsonReader.ReadPropertyName();
                if (string.CompareOrdinal("__metadata", strB) == 0)
                {
                    if (entryState.MetadataPropertyFound)
                    {
                        throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonEntryAndFeedDeserializer_MultipleMetadataPropertiesInEntryValue);
                    }
                    entryState.MetadataPropertyFound = true;
                    base.JsonReader.SkipValue();
                }
                else
                {
                    if (!ValidationUtils.IsValidPropertyName(strB))
                    {
                        base.JsonReader.SkipValue();
                        continue;
                    }
                    IEdmProperty edmProperty = ReaderValidationUtils.FindDefinedProperty(strB, entityType, base.MessageReaderSettings);
                    if (edmProperty != null)
                    {
                        navigationProperty = edmProperty as IEdmNavigationProperty;
                        if (navigationProperty != null)
                        {
                            if (this.ShouldEntryPropertyBeSkipped())
                            {
                                base.JsonReader.SkipValue();
                            }
                            else
                            {
                                bool flag = navigationProperty.Type.IsCollection();
                                navigationLink = new ODataNavigationLink {
                                    Name         = strB,
                                    IsCollection = new bool?(flag)
                                };
                                this.ValidateNavigationLinkPropertyValue(flag);
                                entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNamesOnNavigationLinkStart(navigationLink);
                            }
                        }
                        else
                        {
                            this.ReadEntryProperty(entryState, edmProperty);
                        }
                    }
                    else if (entityType.IsOpen)
                    {
                        if (this.ShouldEntryPropertyBeSkipped())
                        {
                            base.JsonReader.SkipValue();
                        }
                        else
                        {
                            this.ReadOpenProperty(entryState, strB);
                        }
                    }
                    else
                    {
                        navigationLink = this.ReadUndeclaredProperty(entryState, strB);
                    }
                }
                if (navigationLink != null)
                {
                    return(navigationLink);
                }
            }
            return(navigationLink);
        }
 internal void ValidateEntryMetadata(IODataJsonReaderEntryState entryState)
 {
     ODataEntry entry = entryState.Entry;
     IEdmEntityType entityType = entryState.EntityType;
     if (base.Model.HasDefaultStream(entityType) && (entry.MediaResource == null))
     {
         ODataStreamReferenceValue instance = null;
         ODataJsonReaderUtils.EnsureInstance<ODataStreamReferenceValue>(ref instance);
         entry.MediaResource = instance;
     }
     bool useDefaultFormatBehavior = base.UseDefaultFormatBehavior;
     ValidationUtils.ValidateEntryMetadata(entry, entityType, base.Model, useDefaultFormatBehavior);
 }
 internal void ReadEntryMetadataPropertyValue(IODataJsonReaderEntryState entryState)
 {
     ODataEntry entry = entryState.Entry;
     base.JsonReader.ReadStartObject();
     ODataStreamReferenceValue mediaResource = null;
     ODataJsonReaderUtils.MetadataPropertyBitMask none = ODataJsonReaderUtils.MetadataPropertyBitMask.None;
     while (base.JsonReader.NodeType == JsonNodeType.Property)
     {
         switch (base.JsonReader.ReadPropertyName())
         {
             case "uri":
             {
                 this.ReadUriMetadataProperty(entry, ref none);
                 continue;
             }
             case "id":
             {
                 this.ReadIdMetadataProperty(entry, ref none);
                 continue;
             }
             case "etag":
             {
                 this.ReadETagMetadataProperty(entry, ref none);
                 continue;
             }
             case "type":
             {
                 base.JsonReader.SkipValue();
                 continue;
             }
             case "media_src":
             {
                 this.ReadMediaSourceMetadataProperty(ref none, ref mediaResource);
                 continue;
             }
             case "edit_media":
             {
                 this.ReadEditMediaMetadataProperty(ref none, ref mediaResource);
                 continue;
             }
             case "content_type":
             {
                 this.ReadContentTypeMetadataProperty(ref none, ref mediaResource);
                 continue;
             }
             case "media_etag":
             {
                 this.ReadMediaETagMetadataProperty(ref none, ref mediaResource);
                 continue;
             }
             case "actions":
             {
                 this.ReadActionsMetadataProperty(entry, ref none);
                 continue;
             }
             case "functions":
             {
                 this.ReadFunctionsMetadataProperty(entry, ref none);
                 continue;
             }
             case "properties":
             {
                 this.ReadPropertiesMetadataProperty(entryState, ref none);
                 continue;
             }
         }
         base.JsonReader.SkipValue();
     }
     entry.MediaResource = mediaResource;
 }
 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);
     }
 }