Ricardo Figueiredo
Ricardo Figueiredo

Reputation: 216

Getting Azure AD users is taking way to much time! How to reduce the time?

I am getting Azure AD users into a list to be used in a dropdown, but it takes about at least 8/9 seconds to do the call... I know this can probably be reduced... So I will place my code here, hoping that someone can give me a better idea of how to change the code to a better one.

 public async Task<List<Microsoft.Graph.User>> getAzureUsers()
        {
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create("***")
                .WithTenantId("***")
                .WithClientSecret("***")
                .Build();

            ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

            GraphServiceClient graphClient = new GraphServiceClient(authProvider);

            List<Microsoft.Graph.User> utilizadores = new List<Microsoft.Graph.User>();
            

            var user = await graphClient.Users
                .Request()
                .Select(p => new {
                    p.DisplayName,
                    p.UserPrincipalName,
                    p.Id
                })
                .GetAsync();

            utilizadores.AddRange(user.CurrentPage);

            while (user.NextPageRequest != null)
            {
                user = await user.NextPageRequest.GetAsync();
                utilizadores.AddRange(user.CurrentPage);
            }

            return utilizadores;
        }
 public async Task<ViewModelColaboradores> GetVM()
        {
            bool colExist = false;

            List<Microsoft.Graph.User> utilizadores = new List<Microsoft.Graph.User>();
            List<UserAD> nomes = new List<UserAD>();
            utilizadores = await getAzureUsers();

            ViewModelColaboradores vm = new ViewModelColaboradores();
            foreach (var n in utilizadores)
            {
                foreach (var col in _context.RH_Colaboradores)
                {
                    if (n.DisplayName == col.Nome)
                    {
                        colExist = true;
                    }
                }
                if (!colExist)
                {

                    nomes.Add(new UserAD { DisplayName = n.DisplayName, Id = n.Id, Email = n.UserPrincipalName });
                }
                colExist = false;
            }
            vm.usersAd = nomes;

            return vm;
        }

and then I just call GETVM to get the viewmodel with the users inside. Any ideas?

Upvotes: 0

Views: 1320

Answers (1)

Harshita Singh
Harshita Singh

Reputation: 4870

You can use pagination to improve the performance.

You can have a search-based dropdown(non-paginated) or scroll based dropdown (paginated - that fetches new items on scrolling down and fetches scroll up results from cache).

C# sample code:

public async Task<AzureUserDto> GetUsersPage(int pageSize, string skipToken)
{
    var filterString = $"startswith(givenName, '{firstName}')";

    var queryOptions = new List<QueryOption>
    {
        new QueryOption("$top", pageSize)
    };

    if (!string.IsNullOrEmpty(skipToken))
    {
        queryOptions.Add(new QueryOption("$skiptoken", skipToken));
    }

    var azureUsers = await GraphServiceClient.Users
            .Request(queryOptions)
            .Filter(filterString)
            .Select(x => new
            {
                x.Id,
                x.DisplayName,
                x.GivenName,
                x.Surname,
                x.UserPrincipalName,
                x.AccountEnabled,
                x.Identities,
                x.BusinessPhones,
                x.JobTitle,
                x.MobilePhone,
                x.OfficeLocation,
                x.PreferredLanguage,
                x.Mail
            })
            .GetAsync();

    // Get SkipToken, if exists
    var skipToken = azureUsers
        .NextPageRequest?
        .QueryOptions?
        .FirstOrDefault(
            x => string.Equals("$skiptoken", x.Name, StringComparison.InvariantCultureIgnoreCase))?
        .Value;

    var azureUserDto = new AzureUserDto
    {
        // Map the azureUsers to AzureUsersDto or something similar and return
        // don't forget to include the SkipToken
    };

    return azureUsers;
}

For more details on how to implement the latter method, you can visit Paging Microsoft Graph data in your app and Microsoft Graph API: C# / Filtering / Pagination.

Upvotes: 1

Related Questions