microsoftgraph / msgraph-sdk-dotnet

Microsoft Graph Client Library for .NET!
https://graph.microsoft.com
Other
699 stars 247 forks source link

PageIterator<ManagedDevice> only returns first page? #1125

Closed Hipster74 closed 3 years ago

Hipster74 commented 3 years ago

Describe the bug Using the Graphclient to retrieve managed devices (graphClient.DeviceManagement.ManagedDevices) from tenant with over 1000 devices, then using the PageIterator<ManagedDevice>.CreatePageIterator to get all devices does not produce expected result.

I only get the first page(1000 ManagedDevice default value), PageIterator does not seem to iterate through the other pages.

To Reproduce


List<ManagedDevice> mDevices = new List<ManagedDevice>();
var managedDevices = graphClient.DeviceManagement.ManagedDevices.Request().GetAsync().Result;

var pageIterator = PageIterator<ManagedDevice>.CreatePageIterator(
    graphClient,
    managedDevices,
    (d) => {
         mDevices.Add(d);
         return true;
     }
);

pageIterator.IterateAsync();
 _logger.LogInformation($"Devices found count {mDevices.count}"); // Count is capped at 1000 devices

It DOES work if I don't use the PageIterator and do like this, but that is cheating :

mDevices.AddRange(managedDevices.CurrentPage);
while (managedDevices.NextPageRequest != null)
 {
     managedDevices = managedDevices.NextPageRequest.GetAsync().Result;
     mDevices.AddRange(managedDevices.CurrentPage);
 }
_logger.LogInformation($"Devices found count {mDevices.count}"); // Count is correct, all 1600+ devices received

Expected behavior Expecting to receive all 1600+ devices from Graph API without having to do anything explicit regarding handling paging, but only receives the first 1000 from the first page.

andrueastman commented 3 years ago

Hey @Hipster74,

Thanks for raising this issue. Are you able to provide the version of the SDK that you are using to replicate this?

andrueastman commented 3 years ago

Also, you will also need to await the pageIterator task. Therefore your sample should be

List<ManagedDevice> mDevices = new List<ManagedDevice>();
var managedDevices = await graphClient.DeviceManagement.ManagedDevices.Request().GetAsync();

var pageIterator = PageIterator<ManagedDevice>.CreatePageIterator(
    graphClient,
    managedDevices,
    (d) => {
         mDevices.Add(d);
         return true;
     }
);

await pageIterator.IterateAsync();// use await
 _logger.LogInformation($"Devices found count {mDevices.count}"); 

Any chance this works out?

Hipster74 commented 3 years ago

@andrueastman

Yes, you are right, I don't have the basics correct here unfortunately, sorry about the fuzz.

I was running this in an Azure Function Isolated worker for the first time so lots of confusion, the method for executing this was not async, that's why I used .Result on the graphClient call, but didn't really reflect on the effect this would have on the .IterateAsync().

Hopefully some other noob will find information given here helpful in the future.

Thank you for your help, appreciate it!