private async Task <DescendantIdsResponse> ExecuteTreePickerIdsRequestAsync(int id, string property, string endpoint, bool bypassCache, TryFunc <string, DescendantIdsResponse> tryGetFromCache, Action <string, DescendantIdsResponse> addToCache)
        {
            if (bypassCache == false && cacheIsAvailable)
            {
                DescendantIdsResponse cacheOut;
                if (tryGetFromCache(id.ToString(), out cacheOut))
                {
                    return(cacheOut);
                }
            }

            var requestWithPolicy = new HttpRequestWithPolicy(this);
            var response          = await requestWithPolicy.Execute(() =>
                                                                    httpClient.GetAsync(string.Format((Target.Url.AbsoluteUri + endpoint), id, property))
                                                                    ).ConfigureAwait(false);

            if (response.Result?.IsSuccessStatusCode == false || response.Outcome == OutcomeType.Failure)
            {
                return(DescendantIdsResponse.Empty);
            }

            string jsonResult = await response.Result.Content.ReadAsStringAsync().ConfigureAwait(false);

            DescendantIdsResponse treePickerIdsResponse = JsonConvert.DeserializeObject <DescendantIdsResponse>(jsonResult);

            if (cacheIsAvailable && !bypassCache && (treePickerIdsResponse.DescendantCount > 0))
            {
                addToCache(treePickerIdsResponse.Origin.ToString(), treePickerIdsResponse);
            }

            return(treePickerIdsResponse);
        }
        public async Task <IDictionary <string, RawContentResponse> > GetPublishedDescendantsOfFolderAsync(string url, bool bypassCache)
        {
            string preparedUrl = PrepareUrlParameter(url);
            DescendantIdsResponse dependants = await ExecuteDescendantIdsRequestAsync(preparedUrl, ApiPath.PublishedDescendantByUrl, bypassCache, DescendantUrlCacheSearch(),
                                                                                      AddDescendantAndUrlIndexToCache(preparedUrl)).ConfigureAwait(false);

            return(await BuildDescendantRawResponse(dependants, bypassCache));
        }
        /// <summary>
        /// Descends through the umbraco content tree pulling back all published contents of a tree picker identified by its property .
        /// The result is represented as a flat dictionary; keyed by the content name.
        /// e.g. resultDictionary["Name of content"]
        /// </summary>
        /// <param name="id">The unique ID of the content, which can be found in the umbraco back office</param>
        /// <param name="property">The 'property' is the property value for the tree picker and is case-insensitive. It contains the list of Ids from the tree picker</param>
        /// <param name="bypassCache">If true - The request will bypass the cache, always going to the server to get the content</param>
        public async Task <IDictionary <string, RawContentResponse> > GetPublishedContentOfTreePickerAsync(int id, string property, bool bypassCache)
        {
            DescendantIdsResponse content = await ExecuteTreePickerIdsRequestAsync(id, property, ApiPath.PublishedIdsOfTreePicker, bypassCache,
                                                                                   TreePickerIdCacheSearch(), AddPickertToCache()).ConfigureAwait(false);

            if (content.DescendantCount == 0)
            {
                return(new Dictionary <string, RawContentResponse>());
            }

            var childRequestTasks             = content.Descendants.Select(contentId => GetPublishedContentIncludingMetadataAsync(contentId, bypassCache));
            var descendantRawContentResponses = await Task.WhenAll(childRequestTasks).ConfigureAwait(false);

            return(descendantRawContentResponses.Where(x => x.Id > 0).ToDictionary(x => x.Name));
        }
        private async Task <IDictionary <string, RawContentResponse> > BuildDescendantRawResponse(DescendantIdsResponse descendant, bool bypassCache)
        {
            if (descendant.DescendantCount == 0)
            {
                return(new Dictionary <string, RawContentResponse>());
            }

            var childRequestTasks             = descendant.Descendants.Select(depId => GetPublishedContentIncludingMetadataAsync(depId, bypassCache));
            var descendantRawContentResponses = await Task.WhenAll(childRequestTasks).ConfigureAwait(false);

            return(descendantRawContentResponses.Where(x => x.Id > 0).ToDictionary(x => x.Name));
        }
        /// <summary>
        /// Descends through the umbraco content tree pulling back all descendants of an 'anchor' node.
        /// The result is represented as a flat dictionary; keyed by the content name.
        /// e.g. resultDictionary["Name of content"]
        /// </summary>
        /// <param name="id">The unique ID of the content, which can be found in the umbraco back office</param>
        /// <param name="bypassCache">If true - The request will bypass the cache, always going to the server to get the content</param>
        public async Task <IDictionary <string, RawContentResponse> > GetPublishedDescendantsOfFolderAsync(int id, bool bypassCache)
        {
            DescendantIdsResponse dependants = await ExecuteDescendantIdsRequestAsync(id, ApiPath.PublishedDescendantIds, bypassCache, DescendantIdCacheSearch(), AddDescendantToCache()).ConfigureAwait(false);

            return(await BuildDescendantRawResponse(dependants, bypassCache));
        }