-
Notifications
You must be signed in to change notification settings - Fork 57
Description
Is your feature request related to a problem? Please describe the problem.
The SDK only supports "server-side" paging using the PageIterator this parsed the NextDataLink and allows to get multiple pages on the server side.
For instance the List MobileApps endpoint.
Describe the solution you'd like.
But what if I want to show some page to user, and not all pages.
I would like to do:
var apps = await graphServiceClient.DeviceAppManagement.MobileApps.GetFromNextLinkAsync(Uri nextDataLink, CancellationToken cancellationToken);
Then I can pass the nextDataLink to the user and allow very efficient loading of pages.
I also considered parsing the NextDataLink uri and extracting the $SkipToken
query parameter, but this is not supported:
var apps = await graphServiceClient.DeviceAppManagement.MobileApps.GetAsync(req => {
req.QueryParameters.SkipToken = "..."; // This does not exists 🙄
}, cancellationToken);
Additional context?
You have a lot of "list" endpoints. You can get all items server side using a PageIterator, but you cannot easily make the client browse a list efficiently.
I think that every endpoint that returns a SomethingCollectionResponse
should also have a GetAsync(Uri nextLink, CancellationToken cancellationToken)
overload!
Otherwise we are all forced to start creating Extensions for the client that does something like:
msgraph-sdk-dotnet-core/src/Microsoft.Graph.Core/Tasks/PageIterator.cs
Lines 249 to 282 in aee5848
private async Task InterpageIterateAsync(CancellationToken token) | |
{ | |
State = PagingState.InterpageIteration; | |
// Get the next page if it is available and queue the items for processing. | |
if (!string.IsNullOrEmpty(Nextlink) || !string.IsNullOrEmpty(Deltalink)) | |
{ | |
// Call the MSGraph API to get the next page of results and set that page as the currentPage. | |
var nextPageRequestInformation = new RequestInformation | |
{ | |
HttpMethod = Method.GET, | |
UrlTemplate = string.IsNullOrEmpty(Nextlink) ? Deltalink : Nextlink, | |
}; | |
// if we have a request configurator, modify the request as desired then execute it to get the next page | |
nextPageRequestInformation = _requestConfigurator == null ? nextPageRequestInformation : _requestConfigurator(nextPageRequestInformation); | |
_currentPage = await _requestAdapter.SendAsync<TCollectionPage>(nextPageRequestInformation, (parseNode) => new TCollectionPage(), _errorMapping, token); | |
var pageItems = ExtractEntityListFromParsable(_currentPage); | |
// Add all of the items returned in the response to the queue. | |
if (pageItems != null && pageItems.Count > 0) | |
{ | |
foreach (TEntity entity in pageItems) | |
{ | |
_pageItemQueue.Enqueue(entity); | |
} | |
} | |
} | |
// Detect nextLink loop | |
if (!string.IsNullOrEmpty(Nextlink) && Nextlink.Equals(ExtractNextLinkFromParsable(_currentPage))) | |
{ | |
throw new ServiceException($"Detected nextLink loop. Nextlink value: {Nextlink}"); | |
} | |
} |