It is required to use @odata.nextLink - Microsoft Graph - C#

Carlos Jahir Carreño Hernandez 125 Reputation points
2023-11-12T02:43:10.0666667+00:00

A development has been carried out in C# to attract two Microsoft Graph queries. The code works perfectly, but it only brings me 100 devices out of the 2000 that I have. So, in some way, I want to take the Odata.nexlink variables to bring the rest of the devices through the code, but I have not yet found the answer. I want this query to bring me the 2000 devices.

using System;
using System.Linq;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.Graph;
using Newtonsoft.Json;
using Microsoft.Kiota.Http.HttpClientLibrary;

namespace new_project
{
    public class ResponseData
    {
        public string DeviceId { get; set; }
        public string DeviceName { get; set; }
        //public List<string> PolicyNames { get; set; }
        public string OperatingSystem { get; set; }

        public ResponseData(string deviceId, string deviceName, string operatingSystem)
        {
            DeviceId = deviceId;
            //this.PolicyNames = policyNames;
            DeviceName = deviceName;
            OperatingSystem = operatingSystem;
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            // Authentication section for the created application in Azure

            string[] scopes = { "https://graph.microsoft.com/.default" };
            var clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
            var tenantId = "xxxxxxxxxxxxxxxxxxxx";
            var clientSecret = "xxxxxxxxxxxxxxxxxxxxx";

            var options = new ClientSecretCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);

            var responseList = new List<ResponseData>();
            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

            // Microsoft Graph queries
            var devices = await graphClient.Devices.GetAsync();

            // Corrected loop to iterate over pages of devices
            while (devices.OdataNextLink != null)
            {
                // Process the current page of devices
                foreach (var device in devices.Value)
                {
                    var deviceId = device.DeviceId.ToString();
                    var displayName = device.DisplayName.ToString();
                    var operatingSystem = device.OperatingSystem.ToString();

                    try
                    {
                        responseList.Add(new ResponseData(deviceId, displayName, operatingSystem));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error getting device compliance policy states for device {deviceId}: {ex.Message}");
                    }
                }

                // Get the next page of devices
                devices = await graphClient.Devices.GetAsync((requestConfiguration) =>
                {
                    requestConfiguration.QueryParameters.Top = 50;
                    requestConfiguration.QueryParameters.Skiptoken = "RFNwdAIAAQAAACtEZXZpY2VfMDFiN2QyYzEtMmE1My00YzdlLTlkMjYtOGMyOTgxZjYxMDNkK0RldmljZV8wMWI3ZDJjMS0yYTUzLTRjN2UtOWQyNi04YzI5ODFmNjEwM2QAAAAAAAAAAAAAAA";
                });
            
            }
            Console.WriteLine(JsonConvert.SerializeObject(responseList, Formatting.Indented));
        }
    }
}
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
11,785 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,821 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Vasil Michev 103.5K Reputation points MVP
    2023-11-12T15:28:09.2033333+00:00

    Refer to the official documentation on how to handle pagination: https://learn.microsoft.com/en-us/graph/paging?tabs=csharp

    https://learn.microsoft.com/en-us/graph/sdks/paging?tabs=csharp

    The documentation has examples in all major languages supported by the SDK, use them.

    0 comments No comments

  2. Carlos Jahir Carreño Hernandez 125 Reputation points
    2023-11-14T15:00:08.4633333+00:00

    I've made some adjustments to the code, such as renaming the variable 'dispositivos' to 'devices' and 'dispositivoId' to 'deviceId' for consistency in English. I also corrected the check for an empty 'devices' collection in the condition. Additionally, some parts of the code seem to be commented out; ensure to revise and uncomment if necessary to ensure proper functionality.

    
    private static async Task getDevices(GraphServiceClient graphClient, string nextLink = "")
    
    {
    
        DeviceCollectionResponse devices;
    
        if (nextLink == "" && !devices.Any())
    
        {
    
            devices = await graphClient.Devices.GetAsync();
    
            /*devices = await graphClient.Devices.GetAsync(o =>
    
            {
    
                o.QueryParameters. = 5;
    
            });
    
            */
    
        }
    
        else
    
        {
    
            var nextPageRequestInformation = new RequestInformation
    
            {
    
                HttpMethod = Method.GET,
    
                UrlTemplate = nextLink
    
            };
    
            devices = await graphClient.RequestAdapter.SendAsync(nextPageRequestInformation, (parseNode) => new DeviceCollectionResponse());
    
        }
    
        foreach (var device in devices.Value)
    
        {
    
            var deviceId = device.DeviceId.ToString();
    
            var displayName = device.DisplayName.ToString();
    
            var os = device.OperatingSystem.ToString();
    
            devices.Add(new Device(deviceId, displayName, os, new List<Policy>()));
    
        }
    
        var nextPageLink = devices.OdataNextLink;
    
        if (nextPageLink != null)
    
        {
    
            await getDevices(graphClient, nextPageLink);
    
        }
    
    }
    
    
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.