コード例 #1
0
        /// <summary>
        /// Get the page size.
        /// </summary>
        /// <param name="actionExecutedContext">The response value.</param>
        /// <param name="responseValue">The response value.</param>
        /// <param name="singleResultCollection">The content as SingleResult.Queryable.</param>
        /// <param name="actionDescriptor">The action context, i.e. action and controller name.</param>
        /// <param name="request">The request.</param>
        private void GetModelBoundPageSize(
            ActionExecutedContext actionExecutedContext,
            object responseValue,
            IQueryable singleResultCollection,
            ControllerActionDescriptor actionDescriptor,
            HttpRequest request)
        {
            ODataQueryContext queryContext;

            try
            {
                queryContext = GetODataQueryContext(responseValue, singleResultCollection, actionDescriptor, request);
            }
            catch (InvalidOperationException e)
            {
                actionExecutedContext.Result = CreateBadRequestResult(Error.Format(SRResources.UriQueryStringInvalid, e.Message), e);
                return;
            }

            ModelBoundQuerySettings querySettings = EdmHelpers.GetModelBoundQuerySettings(queryContext.TargetProperty,
                                                                                          queryContext.TargetStructuredType,
                                                                                          queryContext.Model);

            if (querySettings != null && querySettings.PageSize.HasValue)
            {
                _querySettings.ModelBoundPageSize = querySettings.PageSize;
            }
        }
コード例 #2
0
 /// <summary>
 /// Copy the $select configuration of properties.
 /// </summary>
 internal static void CopySelectConfigurations(this ModelBoundQuerySettings settings, Dictionary <string, SelectExpandType> selectConfigurations)
 {
     settings.SelectConfigurations.Clear();
     foreach (var selectConfiguration in selectConfigurations)
     {
         settings.SelectConfigurations.Add(selectConfiguration.Key, selectConfiguration.Value);
     }
 }
コード例 #3
0
 /// <summary>
 /// Copy the $filter configuration of properties.
 /// </summary>
 internal static void CopyFilterConfigurations(this ModelBoundQuerySettings settings, Dictionary <string, bool> filterConfigurations)
 {
     settings.FilterConfigurations.Clear();
     foreach (var filterConfiguration in filterConfigurations)
     {
         settings.FilterConfigurations.Add(filterConfiguration.Key, filterConfiguration.Value);
     }
 }
コード例 #4
0
 /// <summary>
 /// Copy the $orderby configuration of properties.
 /// </summary>
 internal static void CopyOrderByConfigurations(this ModelBoundQuerySettings settings, Dictionary <string, bool> orderByConfigurations)
 {
     settings.OrderByConfigurations.Clear();
     foreach (var orderByConfiguration in orderByConfigurations)
     {
         settings.OrderByConfigurations.Add(orderByConfiguration.Key, orderByConfiguration.Value);
     }
 }
コード例 #5
0
 /// <summary>
 /// Copy the <see cref="ExpandConfiguration"/>s of navigation properties.
 /// </summary>
 internal static void CopyExpandConfigurations(this ModelBoundQuerySettings settings, Dictionary <string, ExpandConfiguration> expandConfigurations)
 {
     settings.ExpandConfigurations.Clear();
     foreach (var expandConfiguration in expandConfigurations)
     {
         settings.ExpandConfigurations.Add(expandConfiguration.Key, expandConfiguration.Value);
     }
 }
コード例 #6
0
        // Process $levels in SelectedItems.
        private IEnumerable <SelectItem> ProcessLevels(
            IEnumerable <SelectItem> selectItems,
            int levelsMaxLiteralExpansionDepth,
            ModelBoundQuerySettings querySettings,
            out bool levelsEncountered,
            out bool isMaxLevel)
        {
            levelsEncountered = false;
            isMaxLevel        = false;
            IList <SelectItem> items = new List <SelectItem>();

            foreach (SelectItem selectItem in selectItems)
            {
                ExpandedNavigationSelectItem item = selectItem as ExpandedNavigationSelectItem;

                if (item == null)
                {
                    // There is no $levels in non-ExpandedNavigationSelectItem.
                    items.Add(selectItem);
                }
                else
                {
                    bool levelsEncouteredInExpand;
                    bool isMaxLevelInExpand;
                    // Process $levels in ExpandedNavigationSelectItem.
                    ExpandedNavigationSelectItem expandItem = ProcessLevels(
                        item,
                        levelsMaxLiteralExpansionDepth,
                        querySettings,
                        out levelsEncouteredInExpand,
                        out isMaxLevelInExpand);

                    if (item.LevelsOption != null && item.LevelsOption.Level > 0 && expandItem == null)
                    {
                        // Abandon this attempt if any of the items failed to expand
                        return(null);
                    }
                    else if (item.LevelsOption != null)
                    {
                        // The expansion would be volatile if any of the expand item is max level
                        isMaxLevel = isMaxLevel || isMaxLevelInExpand;
                    }

                    levelsEncountered = levelsEncountered || levelsEncouteredInExpand;

                    if (expandItem != null)
                    {
                        items.Add(expandItem);
                    }
                }
            }
            return(items);
        }
コード例 #7
0
        internal SelectExpandClause ProcessLevels()
        {
            bool levelsEncountered;
            bool isMaxLevel;
            ModelBoundQuerySettings querySettings = Context.Model.GetModelBoundQuerySettings(Context.TargetProperty,
                                                                                             Context.TargetStructuredType, Context.DefaultQuerySettings);

            return(ProcessLevels(SelectExpandClause,
                                 LevelsMaxLiteralExpansionDepth < 0 ? ODataValidationSettings.DefaultMaxExpansionDepth : LevelsMaxLiteralExpansionDepth,
                                 querySettings,
                                 out levelsEncountered,
                                 out isMaxLevel));
        }
コード例 #8
0
        internal static bool Expandable(this ModelBoundQuerySettings settings, string propertyName)
        {
            ExpandConfiguration expandConfiguration;

            if (settings.ExpandConfigurations.TryGetValue(propertyName, out expandConfiguration))
            {
                return(expandConfiguration.ExpandType != SelectExpandType.Disabled);
            }
            else
            {
                return(settings.DefaultExpandType.HasValue && settings.DefaultExpandType != SelectExpandType.Disabled);
            }
        }
コード例 #9
0
        internal static bool IsAutomaticSelect(this ModelBoundQuerySettings settings, string propertyName)
        {
            SelectExpandType selectExpandType;

            if (settings.SelectConfigurations.TryGetValue(propertyName, out selectExpandType))
            {
                return(selectExpandType == SelectExpandType.Automatic);
            }
            else
            {
                return(settings.DefaultSelectType.HasValue && settings.DefaultSelectType == SelectExpandType.Automatic);
            }
        }
コード例 #10
0
        internal static bool Filterable(this ModelBoundQuerySettings settings, string propertyName)
        {
            bool enable;

            if (settings.FilterConfigurations.TryGetValue(propertyName, out enable))
            {
                return(enable);
            }
            else
            {
                return(settings.DefaultEnableFilter == true);
            }
        }
コード例 #11
0
        /// <summary>
        /// Copy and create new instance of the <see cref="ModelBoundQuerySettings"/> class
        /// </summary>
        public ModelBoundQuerySettings(ModelBoundQuerySettings querySettings)
        {
            if (querySettings == null)
            {
                throw new ArgumentNullException(nameof(querySettings));
            }

            _maxTop              = querySettings.MaxTop;
            PageSize             = querySettings.PageSize;
            Countable            = querySettings.Countable;
            DefaultEnableFilter  = querySettings.DefaultEnableFilter;
            DefaultEnableOrderBy = querySettings.DefaultEnableOrderBy;
            DefaultExpandType    = querySettings.DefaultExpandType;
            DefaultMaxDepth      = querySettings.DefaultMaxDepth;
            DefaultSelectType    = querySettings.DefaultSelectType;
            CopyOrderByConfigurations(querySettings.OrderByConfigurations);
            CopyFilterConfigurations(querySettings.FilterConfigurations);
            CopyExpandConfigurations(querySettings.ExpandConfigurations);
            CopySelectConfigurations(querySettings.SelectConfigurations);
        }
コード例 #12
0
        private static int GetMaxExpandDepth(ModelBoundQuerySettings querySettings, string propertyName)
        {
            int result = 0;

            if (querySettings != null)
            {
                ExpandConfiguration expandConfiguration;
                if (querySettings.ExpandConfigurations.TryGetValue(propertyName, out expandConfiguration))
                {
                    result = expandConfiguration.MaxDepth;
                }
                else
                {
                    if (querySettings.DefaultExpandType.HasValue &&
                        querySettings.DefaultExpandType != SelectExpandType.Disabled)
                    {
                        result = querySettings.DefaultMaxDepth;
                    }
                }
            }

            return(result);
        }
コード例 #13
0
        // Process $levels in SelectExpandClause.
        private SelectExpandClause ProcessLevels(
            SelectExpandClause selectExpandClause,
            int levelsMaxLiteralExpansionDepth,
            ModelBoundQuerySettings querySettings,
            out bool levelsEncountered,
            out bool isMaxLevel)
        {
            levelsEncountered = false;
            isMaxLevel        = false;

            if (selectExpandClause == null)
            {
                return(null);
            }

            // Process $levels in SelectItems of SelectExpandClause.
            IEnumerable <SelectItem> selectItems = ProcessLevels(
                selectExpandClause.SelectedItems,
                levelsMaxLiteralExpansionDepth,
                querySettings,
                out levelsEncountered,
                out isMaxLevel);

            if (selectItems == null)
            {
                return(null);
            }
            else if (levelsEncountered)
            {
                return(new SelectExpandClause(selectItems, selectExpandClause.AllSelected));
            }
            else
            {
                // Return the original SelectExpandClause if no $levels is found.
                return(selectExpandClause);
            }
        }
コード例 #14
0
        // Process $levels in ExpandedNavigationSelectItem.
        private ExpandedNavigationSelectItem ProcessLevels(
            ExpandedNavigationSelectItem expandItem,
            int levelsMaxLiteralExpansionDepth,
            ModelBoundQuerySettings querySettings,
            out bool levelsEncounteredInExpand,
            out bool isMaxLevelInExpand)
        {
            int level;

            isMaxLevelInExpand = false;

            if (expandItem.LevelsOption == null)
            {
                levelsEncounteredInExpand = false;
                level = 1;
            }
            else
            {
                levelsEncounteredInExpand = true;
                if (expandItem.LevelsOption.IsMaxLevel)
                {
                    isMaxLevelInExpand = true;
                    level = levelsMaxLiteralExpansionDepth;
                }
                else
                {
                    level = (int)expandItem.LevelsOption.Level;
                }
            }

            // Do not expand when:
            // 1. $levels is equal to or less than 0.
            // 2. $levels value is greater than current MaxExpansionDepth
            if (level <= 0 || level > levelsMaxLiteralExpansionDepth)
            {
                return(null);
            }

            ExpandedNavigationSelectItem item = null;
            SelectExpandClause           currentSelectExpandClause = null;
            SelectExpandClause           selectExpandClause        = null;
            bool levelsEncounteredInInnerExpand = false;
            bool isMaxLevelInInnerExpand        = false;
            var  entityType = expandItem.NavigationSource.EntityType();
            IEdmNavigationProperty navigationProperty =
                (expandItem.PathToNavigationProperty.LastSegment as NavigationPropertySegment).NavigationProperty;
            ModelBoundQuerySettings nestQuerySettings = Context.Model.GetModelBoundQuerySettings(navigationProperty, navigationProperty.ToEntityType());

            // Try different expansion depth until expandItem.SelectAndExpand is successfully expanded
            while (selectExpandClause == null && level > 0)
            {
                selectExpandClause = ProcessLevels(
                    expandItem.SelectAndExpand,
                    levelsMaxLiteralExpansionDepth - level,
                    nestQuerySettings,
                    out levelsEncounteredInInnerExpand,
                    out isMaxLevelInInnerExpand);
                level--;
            }

            if (selectExpandClause == null)
            {
                return(null);
            }

            // Correct level value
            level++;
            List <SelectItem> originAutoSelectItems;
            List <SelectItem> originAutoExpandItems;

            int maxDepth = GetMaxExpandDepth(querySettings, navigationProperty.Name);

            if (maxDepth == 0 || levelsMaxLiteralExpansionDepth > maxDepth)
            {
                maxDepth = levelsMaxLiteralExpansionDepth;
            }

            GetAutoSelectExpandItems(
                entityType,
                Context.Model,
                expandItem.NavigationSource,
                selectExpandClause.AllSelected,
                nestQuerySettings,
                maxDepth - 1,
                out originAutoSelectItems,
                out originAutoExpandItems);
            if (expandItem.SelectAndExpand.SelectedItems.Any(it => it is PathSelectItem))
            {
                originAutoSelectItems.Clear();
            }

            if (level > 1)
            {
                RemoveSameExpandItem(navigationProperty, originAutoExpandItems);
            }

            List <SelectItem> autoExpandItems = new List <SelectItem>(originAutoExpandItems);
            bool hasAutoSelectExpandInExpand  = (originAutoSelectItems.Count + originAutoExpandItems.Count != 0);
            bool allSelected = originAutoSelectItems.Count == 0 && selectExpandClause.AllSelected;

            while (level > 0)
            {
                autoExpandItems = RemoveExpandItemExceedMaxDepth(maxDepth - level, originAutoExpandItems);
                if (item == null)
                {
                    if (hasAutoSelectExpandInExpand)
                    {
                        currentSelectExpandClause = new SelectExpandClause(
                            Array.Empty <SelectItem>().Concat(selectExpandClause.SelectedItems)
                            .Concat(originAutoSelectItems).Concat(autoExpandItems),
                            allSelected);
                    }
                    else
                    {
                        currentSelectExpandClause = selectExpandClause;
                    }
                }
                else if (selectExpandClause.AllSelected)
                {
                    // Concat the processed items
                    currentSelectExpandClause = new SelectExpandClause(
                        new SelectItem[] { item }.Concat(selectExpandClause.SelectedItems)
                        .Concat(originAutoSelectItems).Concat(autoExpandItems),
                        allSelected);
                }
                else
                {
                    // PathSelectItem is needed for the expanded item if AllSelected is false.
                    PathSelectItem pathSelectItem = new PathSelectItem(
                        new ODataSelectPath(expandItem.PathToNavigationProperty));

                    // Keep default SelectItems before expanded item to keep consistent with normal SelectExpandClause
                    SelectItem[] items = new SelectItem[] { item, pathSelectItem };
                    currentSelectExpandClause = new SelectExpandClause(
                        Array.Empty <SelectItem>().Concat(selectExpandClause.SelectedItems)
                        .Concat(items)
                        .Concat(originAutoSelectItems).Concat(autoExpandItems),
                        allSelected);
                }

                // Construct a new ExpandedNavigationSelectItem with current SelectExpandClause.
                item = new ExpandedNavigationSelectItem(
                    expandItem.PathToNavigationProperty,
                    expandItem.NavigationSource,
                    currentSelectExpandClause,
                    expandItem.FilterOption,
                    expandItem.OrderByOption,
                    expandItem.TopOption,
                    expandItem.SkipOption,
                    expandItem.CountOption,
                    expandItem.SearchOption,
                    null,
                    expandItem.ComputeOption,
                    expandItem.ApplyOption);

                level--;

                // Need expand and construct selectExpandClause every time if it is max level in inner expand
                if (isMaxLevelInInnerExpand)
                {
                    selectExpandClause = ProcessLevels(
                        expandItem.SelectAndExpand,
                        levelsMaxLiteralExpansionDepth - level,
                        nestQuerySettings,
                        out levelsEncounteredInInnerExpand,
                        out isMaxLevelInInnerExpand);
                }
            }

            levelsEncounteredInExpand = levelsEncounteredInExpand || levelsEncounteredInInnerExpand || hasAutoSelectExpandInExpand;
            isMaxLevelInExpand        = isMaxLevelInExpand || isMaxLevelInInnerExpand;

            return(item);
        }
コード例 #15
0
        private void GetAutoSelectExpandItems(IEdmEntityType baseEntityType, IEdmModel model, IEdmNavigationSource navigationSource, bool isAllSelected,
                                              ModelBoundQuerySettings modelBoundQuerySettings, int depth, out List <SelectItem> autoSelectItems, out List <SelectItem> autoExpandItems)
        {
            autoSelectItems = new List <SelectItem>();
            autoExpandItems = new List <SelectItem>();

            if (baseEntityType == null)
            {
                return;
            }

            IList <SelectModelPath> autoSelectProperties = model.GetAutoSelectPaths(baseEntityType, null, modelBoundQuerySettings);

            foreach (var autoSelectProperty in autoSelectProperties)
            {
                ODataSelectPath odataSelectPath = BuildSelectPath(autoSelectProperty, navigationSource);
                PathSelectItem  pathSelectItem  = new PathSelectItem(odataSelectPath);
                autoSelectItems.Add(pathSelectItem);
            }

            depth--;
            if (depth < 0)
            {
                return;
            }

            IList <ExpandModelPath> autoExpandNavigationProperties = model.GetAutoExpandPaths(baseEntityType, null, !isAllSelected, modelBoundQuerySettings);

            foreach (ExpandModelPath itemPath in autoExpandNavigationProperties)
            {
                string navigationPath = itemPath.NavigationPropertyPath;
                IEdmNavigationProperty navigationProperty = itemPath.Navigation;

                IEdmNavigationSource currentEdmNavigationSource;
                if (navigationPath != null)
                {
                    currentEdmNavigationSource = navigationSource.FindNavigationTarget(navigationProperty);
                }
                else
                {
                    currentEdmNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, new EdmPathExpression(navigationPath));
                }

                if (currentEdmNavigationSource != null)
                {
                    ODataExpandPath expandPath = BuildExpandPath(itemPath, navigationSource, currentEdmNavigationSource);

                    SelectExpandClause           selectExpandClause = new SelectExpandClause(new List <SelectItem>(), true);
                    ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource, selectExpandClause);
                    modelBoundQuerySettings = model.GetModelBoundQuerySettings(navigationProperty, navigationProperty.ToEntityType());
                    List <SelectItem> nestedSelectItems;
                    List <SelectItem> nestedExpandItems;

                    int maxExpandDepth = GetMaxExpandDepth(modelBoundQuerySettings, navigationProperty.Name);
                    if (maxExpandDepth != 0 && maxExpandDepth < depth)
                    {
                        depth = maxExpandDepth;
                    }

                    GetAutoSelectExpandItems(
                        currentEdmNavigationSource.EntityType(),
                        model,
                        item.NavigationSource,
                        true,
                        modelBoundQuerySettings,
                        depth,
                        out nestedSelectItems,
                        out nestedExpandItems);

                    selectExpandClause = new SelectExpandClause(nestedSelectItems.Concat(nestedExpandItems), nestedSelectItems.Count == 0);
                    item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource, selectExpandClause);

                    autoExpandItems.Add(item);
                    if (!isAllSelected || autoSelectProperties.Any())
                    {
                        PathSelectItem pathSelectItem = new PathSelectItem(new ODataSelectPath(expandPath));
                        autoExpandItems.Add(pathSelectItem);
                    }
                }
            }
        }
コード例 #16
0
        private void GetAutoSelectExpandItems(
            IEdmEntityType baseEntityType,
            IEdmModel model,
            IEdmNavigationSource navigationSource,
            bool isAllSelected,
            ModelBoundQuerySettings modelBoundQuerySettings,
            int depth,
            out List <SelectItem> autoSelectItems,
            out List <SelectItem> autoExpandItems)
        {
            autoSelectItems = new List <SelectItem>();
            autoExpandItems = new List <SelectItem>();
            var autoSelectProperties = EdmHelpers.GetAutoSelectProperties(null,
                                                                          baseEntityType, model, modelBoundQuerySettings);

            foreach (var autoSelectProperty in autoSelectProperties)
            {
                List <ODataPathSegment> pathSegments = new List <ODataPathSegment>()
                {
                    new PropertySegment(autoSelectProperty)
                };

                PathSelectItem pathSelectItem = new PathSelectItem(
                    new ODataSelectPath(pathSegments));
                autoSelectItems.Add(pathSelectItem);
            }

            depth--;
            if (depth < 0)
            {
                return;
            }

            var autoExpandNavigationProperties = EdmHelpers.GetAutoExpandNavigationProperties(null, baseEntityType,
                                                                                              model, !isAllSelected, modelBoundQuerySettings);

            foreach (var navigationProperty in autoExpandNavigationProperties)
            {
                IEdmNavigationSource currentEdmNavigationSource =
                    navigationSource.FindNavigationTarget(navigationProperty);

                if (currentEdmNavigationSource != null)
                {
                    List <ODataPathSegment> pathSegments = new List <ODataPathSegment>()
                    {
                        new NavigationPropertySegment(navigationProperty, currentEdmNavigationSource)
                    };

                    ODataExpandPath    expandPath         = new ODataExpandPath(pathSegments);
                    SelectExpandClause selectExpandClause = new SelectExpandClause(new List <SelectItem>(),
                                                                                   true);
                    ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath,
                                                                                         currentEdmNavigationSource, selectExpandClause);
                    modelBoundQuerySettings = EdmHelpers.GetModelBoundQuerySettings(navigationProperty,
                                                                                    navigationProperty.ToEntityType(), model);
                    List <SelectItem> nestedSelectItems;
                    List <SelectItem> nestedExpandItems;

                    int maxExpandDepth = GetMaxExpandDepth(modelBoundQuerySettings, navigationProperty.Name);
                    if (maxExpandDepth != 0 && maxExpandDepth < depth)
                    {
                        depth = maxExpandDepth;
                    }

                    GetAutoSelectExpandItems(
                        currentEdmNavigationSource.EntityType(),
                        model,
                        item.NavigationSource,
                        true,
                        modelBoundQuerySettings,
                        depth,
                        out nestedSelectItems,
                        out nestedExpandItems);

                    selectExpandClause = new SelectExpandClause(nestedSelectItems.Concat(nestedExpandItems),
                                                                nestedSelectItems.Count == 0);
                    item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource,
                                                            selectExpandClause);

                    autoExpandItems.Add(item);
                    if (!isAllSelected || autoSelectProperties.Any())
                    {
                        PathSelectItem pathSelectItem = new PathSelectItem(
                            new ODataSelectPath(pathSegments));
                        autoExpandItems.Add(pathSelectItem);
                    }
                }
            }
        }