コード例 #1
0
        internal void CheckForDuplicatePropertyNames(ODataNavigationLink navigationLink, bool isExpanded, bool?isCollection)
        {
            DuplicationRecord record;
            string            name = navigationLink.Name;

            if (!this.TryGetDuplicationRecord(name, out record))
            {
                DuplicationRecord duplicationRecord = new DuplicationRecord(DuplicationKind.NavigationProperty);
                ApplyNavigationLinkToDuplicationRecord(duplicationRecord, isExpanded, isCollection);
                this.propertyNameCache.Add(name, duplicationRecord);
            }
            else
            {
                this.CheckNavigationLinkDuplicateNameForExistingDuplicationRecord(name, record);
                if (((record.DuplicationKind == DuplicationKind.NavigationProperty) && record.AssociationLinkFound) && !record.NavigationLinkFound)
                {
                    ApplyNavigationLinkToDuplicationRecord(record, isExpanded, isCollection);
                }
                else if (this.allowDuplicateProperties)
                {
                    record.DuplicationKind = DuplicationKind.NavigationProperty;
                    ApplyNavigationLinkToDuplicationRecord(record, isExpanded, isCollection);
                }
                else
                {
                    bool?isCollectionEffectiveValue = GetIsCollectionEffectiveValue(isExpanded, isCollection);
                    if ((isCollectionEffectiveValue == false) || (record.NavigationPropertyIsCollection == false))
                    {
                        throw new ODataException(Strings.DuplicatePropertyNamesChecker_MultipleLinksForSingleton(name));
                    }
                    if (isCollectionEffectiveValue.HasValue)
                    {
                        record.NavigationPropertyIsCollection = isCollectionEffectiveValue;
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Check the <paramref name="navigationLink"/> for duplicate property names in an entry or complex value.
        /// If not explicitly allowed throw when duplicate properties are detected.
        /// If duplicate properties are allowed see the comment on ODataWriterBehavior.AllowDuplicatePropertyNames
        /// or ODataReaderBehavior.AllowDuplicatePropertyNames for further details.
        /// </summary>
        /// <param name="navigationLink">The navigation link to be checked.</param>
        /// <param name="isExpanded">true if the link is expanded, false otherwise.</param>
        /// <param name="isCollection">true if the navigation link is a collection, false if it's a singleton or null if we don't know.</param>
        internal void CheckForDuplicatePropertyNames(ODataNavigationLink navigationLink, bool isExpanded, bool?isCollection)
        {
            DebugUtils.CheckNoExternalCallers();
#if DEBUG
            this.startNavigationLinkName = null;
#endif

            string            propertyName = navigationLink.Name;
            DuplicationRecord existingDuplicationRecord;
            if (!this.TryGetDuplicationRecord(propertyName, out existingDuplicationRecord))
            {
                DuplicationRecord duplicationRecord = new DuplicationRecord(DuplicationKind.NavigationProperty);
                ApplyNavigationLinkToDuplicationRecord(duplicationRecord, isExpanded, isCollection);
                this.propertyNameCache.Add(propertyName, duplicationRecord);
            }
            else
            {
                // First check for duplication without expansion knowledge.
                this.CheckNavigationLinkDuplicateNameForExistingDuplicationRecord(propertyName, existingDuplicationRecord);

                if (existingDuplicationRecord.DuplicationKind == DuplicationKind.NavigationProperty &&
                    existingDuplicationRecord.AssociationLinkFound &&
                    !existingDuplicationRecord.NavigationLinkFound)
                {
                    // If the existing one is just an association link, update it to include the navigation link portion as well
                    ApplyNavigationLinkToDuplicationRecord(existingDuplicationRecord, isExpanded, isCollection);
                }
                else if (this.allowDuplicateProperties)
                {
                    Debug.Assert(
                        (existingDuplicationRecord.DuplicationKind == DuplicationKind.PotentiallyAllowed || existingDuplicationRecord.DuplicationKind == DuplicationKind.NavigationProperty),
                        "We should have already taken care of prohibit duplication.");

                    // If the configuration explicitly allows duplication, then just turn the existing property into a nav link with all the information we have
                    existingDuplicationRecord.DuplicationKind = DuplicationKind.NavigationProperty;
                    ApplyNavigationLinkToDuplicationRecord(existingDuplicationRecord, isExpanded, isCollection);
                }
                else
                {
                    // We've found two navigation links in a request
                    Debug.Assert(
                        existingDuplicationRecord.DuplicationKind == DuplicationKind.NavigationProperty && existingDuplicationRecord.NavigationLinkFound && !this.isResponse,
                        "We can only get here if we've found two navigation links in a request.");

                    bool?isCollectionEffectiveValue = GetIsCollectionEffectiveValue(isExpanded, isCollection);

                    // If one of them is a definitive singleton, then we fail.
                    if (isCollectionEffectiveValue == false || existingDuplicationRecord.NavigationPropertyIsCollection == false)
                    {
                        // This is the case where an expanded singleton is followed by a deferred link for example.
                        // Once we know for sure that the nav. prop. is a singleton we can't allow more than one link for it.
                        throw new ODataException(Strings.DuplicatePropertyNamesChecker_MultipleLinksForSingleton(propertyName));
                    }

                    // Otherwise allow it, but update the link with the new information
                    if (isCollectionEffectiveValue.HasValue)
                    {
                        existingDuplicationRecord.NavigationPropertyIsCollection = isCollectionEffectiveValue;
                    }
                }
            }
        }