/// <inheritdoc /> public override async Task <Uri?> GetNextPageLinkAsync(PageLinkData pageLinkData, CancellationToken cancellationToken = default) { if (IsJson(pageLinkData) && pageLinkData.Response != null) { try { using var doc = await JsonDocument.ParseAsync(pageLinkData.Response, cancellationToken : cancellationToken); var hasNextLink = doc.RootElement.TryGetProperty(pageLinkData.NextLinkName, out var nextLink); if (hasNextLink && nextLink.ValueKind == JsonValueKind.String) { string?link = nextLink.GetString(); if (!string.IsNullOrWhiteSpace(link)) { return(new Uri(link)); } } } catch (JsonException) { // If the response isn't valid JSON, there will be no next link. // TODO: Log warning once logging story is defined } } return(null); }
/// <inheritdoc /> public override async Task <Stream?> MergePageAsync(Stream?currentResult, PageLinkData newPageData, CancellationToken cancellationToken = default) { if (IsJson(newPageData)) { return(await MergeJsonStreamsAsync(currentResult, newPageData.Response, newPageData.ItemName, newPageData.NextLinkName, cancellationToken)); } return(null); }
public async Task Return_Null_on_No_Next_Link() { var pagingService = new ODataPagingService(); var requestInfo = new RequestInformation(); var pagingData = new PageLinkData(requestInfo, null); var nextLink = await pagingService.GetNextPageLinkAsync(pagingData); Assert.Null(nextLink); }
public async Task Return_Null_On_Next_Link_Missing() { var pagingService = new ODataPagingService(); var bytes = Encoding.UTF8.GetBytes("{}"); using var ms = new MemoryStream(bytes); var requestInfo = new RequestInformation(); var pagingData = new PageLinkData(requestInfo, ms); var nextLink = await pagingService.GetNextPageLinkAsync(pagingData); Assert.Null(nextLink); }
public async Task Return_Next_Link_From_Response() { var pagingService = new ODataPagingService(); var bytes = Encoding.UTF8.GetBytes("{\"nextLink\": \"https://testlink\"}"); using var ms = new MemoryStream(bytes); var requestInfo = new RequestInformation(); requestInfo.Headers.Add("Accept", "application/json"); var pagingData = new PageLinkData(requestInfo, ms); pagingData.ResponseContentHeaders.Add("Content-Type", new string[] { "application/json" }); var nextLink = await pagingService.GetNextPageLinkAsync(pagingData); Assert.Equal(new Uri("https://testlink"), nextLink); }
/// <inheritdoc /> public virtual async Task <PageResponse?> GetPagedDataAsync(Func <RequestInformation, IResponseHandler, CancellationToken, Task> requestExecutorAsync, PageLinkData pageLinkData, bool fetchAllPages = false, CancellationToken cancellationToken = default) { if (!OnBeforeGetPagedData(pageLinkData, fetchAllPages)) { return(null); } var requestInfo = pageLinkData.RequestInformation; Uri? nextLink; Stream?response = null; int? statusCode; do { var responseHandler = CreateResponseHandler(); await requestExecutorAsync(requestInfo, responseHandler, cancellationToken); var pageData = await responseHandler.GetResponseStreamAsync(cancellationToken); statusCode = responseHandler.GetStatusCode(); var headers = responseHandler.GetResponseHeaders(); var contentHeaders = responseHandler.GetResponseContentHeaders(); pageLinkData = new PageLinkData(requestInfo, pageData, headers, contentHeaders, pageLinkData.ItemName, pageLinkData.NextLinkName); if (fetchAllPages) { nextLink = await GetNextPageLinkAsync(pageLinkData, cancellationToken); if (nextLink != null) { pageLinkData.RequestInformation.URI = nextLink; } } else { nextLink = null; } response = await MergePageAsync(response, pageLinkData, cancellationToken); } while (nextLink != null); return(new PageResponse(statusCode ?? 0, response)); }
private bool IsJson(PageLinkData pageLinkData) { return(pageLinkData.ResponseContentHeaders.TryGetValue("Content-Type", out var contentType) && contentType.Any(c => c.Contains("json"))); }
/// <inheritdoc /> public override bool OnBeforeGetPagedData(PageLinkData pageLinkData, bool fetchAllPages = false) { return(true); }
/// <inheritdoc /> public virtual bool OnBeforeGetPagedData(PageLinkData pageLinkData, bool fetchAllPages = false) { return(true); }
/// <inheritdoc /> public abstract Task <Stream?> MergePageAsync(Stream?currentResult, PageLinkData newPageData, CancellationToken cancellationToken = default);
/// <inheritdoc /> public abstract Task <Uri?> GetNextPageLinkAsync(PageLinkData pageLinkData, CancellationToken cancellationToken = default);