예제 #1
0
        /// <summary>
        /// Call the next page request when there is another page of data.
        /// </summary>
        /// <param name="token"></param>
        /// <returns>The task object that represents the results of this asynchronous operation.</returns>
        /// <exception cref="Microsoft.Graph.ServiceException">Thrown when the service encounters an error with
        /// a request.</exception>
        private async Task InterpageIterateAsync(CancellationToken token)
        {
            State = PagingState.InterpageIteration;

            // Get the next page if it is available and queue the items for processing.
            if (_currentPage.AdditionalData.TryGetValue(Constants.OdataInstanceAnnotations.NextLink, out object nextlink))
            {
                // We need access to the NextPageRequest to call and get the next page. ICollectionPage<TEntity> doesn't define NextPageRequest.
                // We are making this dynamic so we can access NextPageRequest.
                dynamic page = _currentPage;

                // Call the MSGraph API to get the next page of results and set that page as the currentPage.
                _currentPage = await page.NextPageRequest.GetAsync(token).ConfigureAwait(false);

                // Add all of the items returned in the response to the queue.
                if (_currentPage.Count > 0)
                {
                    foreach (TEntity entity in _currentPage)
                    {
                        _pageItemQueue.Enqueue(entity);
                    }
                }
            }

            // Detect nextLink loop
            if (_currentPage.AdditionalData.TryGetValue(Constants.OdataInstanceAnnotations.NextLink, out object nextNextLink) && nextlink.Equals(nextNextLink))
            {
                throw new ServiceException(new Error()
                {
                    Message = $"Detected nextLink loop. Nextlink value: {Nextlink}"
                });
            }
        }
예제 #2
0
        // Uses a page iterator to get all directoryObjects
        // in a collection and cast them to a specific type
        // Will exclude any objects that cannot be case to the
        // requested type
        protected async Task <List <T> > GetAllPagesAsType <T>(
            GraphServiceClient graphClient,
            ICollectionPage <DirectoryObject> page) where T : class
        {
            var allItems = new List <T>();

            var pageIterator = PageIterator <DirectoryObject> .CreatePageIterator(
                graphClient, page,
                (item) => {
                // This code executes for each item in the
                // collection
                if (item is T)
                {
                    // Only add if the item is the requested type
                    allItems.Add(item as T);
                }

                return(true);
            }
                );

            await pageIterator.IterateAsync();

            return(allItems);
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="graphClient">Authenticated GraphServiceClient object.</param>
        /// <param name="page">Result page object from .GetAsync() method</param>
        /// <typeparam name="TSource">Source collection member type (e.g. DirectoryObject, User, Group)</typeparam>
        /// <typeparam name="TResult">Result collection member type (e.g. Group, User)</typeparam>
        /// <returns></returns>
        protected async Task <IEnumerable <TResult>?> AllPagesAsync <TSource, TResult>(
            IBaseClient graphClient, ICollectionPage <TSource> page)
            where TResult : class
        {
            if (page == null)
            {
                return(null);
            }

            var allItems = new List <TResult>();

            var pageIterator = PageIterator <TSource> .CreatePageIterator(
                graphClient, page,
                (item) =>
            {
                // This code executes for each item in the
                // collection
                if (item is TResult t)
                {
                    // Only add if the item is the requested type
                    allItems.Add(t);
                }

                return(true);
            }
                );

            await pageIterator.IterateAsync();

            return(allItems);
        }
 public CollectionPageController
 (
     ILrpNavigation navigation,
     ICollectionPageViewModel <TItem> collectionPageViewModel,
     ICollectionPage <TItem> collectionPage,
     IItemMvcBuilder <TItem> itemMvcBuilder
 )
 {
     _navigation = navigation ?? throw new ArgumentNullException(nameof(navigation));
     _collectionPageViewModel = collectionPageViewModel ?? throw new ArgumentNullException(nameof(collectionPageViewModel));
     _collectionPage          = collectionPage ?? throw new ArgumentNullException(nameof(collectionPage));
     _itemMvcBuilder          = itemMvcBuilder ?? throw new ArgumentNullException(nameof(itemMvcBuilder));
     WirePage();
 }
예제 #5
0
        /// <summary>
        /// Iterate across the content of a a single results page with the callback.
        /// </summary>
        /// <returns>A boolean value that indicates whether the callback cancelled
        /// iterating across the page results or whether there are more pages to page.
        /// A return value of false indicates that the iterator should stop iterating.</returns>
        private bool IntrapageIterate()
        {
            State = PagingState.IntrapageIteration;

            while (_pageItemQueue.Count != 0) // && shouldContinue)
            {
                bool shouldContinue = _processPageItemCallback(_pageItemQueue.Dequeue());

                // Cancel processing of items in the page and stop requesting more pages.
                if (!shouldContinue)
                {
                    State = PagingState.Paused;
                    return(shouldContinue);
                }
            }

            // There are more pages ready to be paged.
            if (_currentPage.AdditionalData.TryGetValue(Constants.OdataInstanceAnnotations.NextLink, out object nextlink))
            {
                Nextlink = nextlink as string;
                return(true);
            }

            // There are no pages CURRENTLY ready to be paged. Attempt to call delta query later.
            else if (_currentPage.AdditionalData.TryGetValue(Constants.OdataInstanceAnnotations.DeltaLink, out object deltalink))
            {
                Deltalink = deltalink as string;
                State     = PagingState.Delta;
                Nextlink  = string.Empty;

                // Setup deltalink request. Using dynamic to access the NextPageRequest.
                dynamic page = _currentPage;
                page.InitializeNextPageRequest(this._client, Deltalink);
                _currentPage = page;

                return(false);
            }

            // Paging has completed - no more nextlinks.
            else
            {
                State    = PagingState.Complete;
                Nextlink = string.Empty;

                return(false);
            }
        }
예제 #6
0
        private static async Task <bool> AnyAsync <TItem>(ICollectionPage <TItem> collectionPage, Func <TItem, bool> predicate)
        {
            dynamic page = collectionPage;

            while (true)
            {
                if (Enumerable.Any(page.CurrentPage, predicate))
                {
                    return(true);
                }
                if (page.NextPageRequest == null)
                {
                    return(false);
                }
                page = await page.NextPageRequest.GetAsync();
            }
        }
예제 #7
0
        private static async Task <TItem[]> GetAllAsync <TItem>(ICollectionPage <TItem> collectionPage)
        {
            var list = new List <TItem>();

            dynamic page = collectionPage;

            while (true)
            {
                list.AddRange(page.CurrentPage);
                if (page.NextPageRequest == null)
                {
                    break;
                }
                page = await page.NextPageRequest.GetAsync();
            }

            return(list.ToArray());
        }
예제 #8
0
        // Uses a page iterator to get all objects in a collection
        protected async Task <List <T> > GetAllPages <T>(
            GraphServiceClient graphClient,
            ICollectionPage <T> page)
        {
            var allItems = new List <T>();

            var pageIterator = PageIterator <T> .CreatePageIterator(
                graphClient, page,
                (item) => {
                // This code executes for each item in the
                // collection
                allItems.Add(item);
                return(true);
            }
                );

            await pageIterator.IterateAsync();

            return(allItems);
        }
예제 #9
0
        /// <summary>
        /// Creates the PageIterator with the results of an initial paged request.
        /// </summary>
        /// <param name="client">The GraphServiceClient object used to create the NextPageRequest for a delta query.</param>
        /// <param name="page">A generated implementation of ICollectionPage.</param>
        /// <param name="callback">A Func delegate that processes type TEntity in the result set and should return false if the iterator should cancel processing.</param>
        /// <returns>A PageIterator&lt;TEntity&gt; that will process additional result pages based on the rules specified in Func&lt;TEntity,bool&gt; processPageItems</returns>
        public static PageIterator <TEntity> CreatePageIterator(IBaseClient client, ICollectionPage <TEntity> page, Func <TEntity, bool> callback)
        {
            if (page == null)
            {
                throw new ArgumentNullException("page");
            }

            if (callback == null)
            {
                throw new ArgumentNullException("processPageItems");
            }

            return(new PageIterator <TEntity>()
            {
                _client = client,
                _currentPage = page,
                _pageItemQueue = new Queue <TEntity>(page),
                _processPageItemCallback = callback,
                State = PagingState.NotStarted
            });
        }
        /// <summary>Patches missing page context for the given collection and page index.</summary>
        /// <param name="collection">The collection.</param>
        /// <param name="pageIndex">The page index.</param>
        /// <typeparam name="T">The type of values in the collection.</typeparam>
        /// <exception cref="ArgumentNullException">The value of <paramref name="collection"/> is a null reference.</exception>
        public static void Patch <T>(ICollectionPage <T> collection, int pageIndex)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection", "Precondition: collection != null");
            }

            collection.PageIndex = pageIndex;
            if (collection.PageCount > 0)
            {
                collection.LastPageIndex = collection.PageCount - 1;
                if (collection.PageIndex < collection.LastPageIndex)
                {
                    collection.NextPageIndex = collection.PageIndex + 1;
                }

                if (collection.PageIndex > collection.FirstPageIndex)
                {
                    collection.PreviousPageIndex = collection.PageIndex - 1;
                }
            }
        }
예제 #11
0
 public static string GetNextLink <T>(this ICollectionPage <T> page)
 {
     return(page.AdditionalData[NEXT_LINK].ToString());
 }
예제 #12
0
 public static string GetDeltaLink <T>(this ICollectionPage <T> page)
 {
     return(page.AdditionalData[DELTA_LINK].ToString());
 }