Search code examples
microsoft-graph-apimicrosoft-graph-sdksmicrosoft-graph-batch

How to use Batch for get response?


I'm working on with Graph SDK v5.56 (.NET). I'm trying to get all the drive ID using the sites list. Other reference show the way to call API for each time using each requestID, but I want to get all the batch response at a onetime. Below is a code I'm working, having error with GetResponseAsync()

private List<(string SiteId, string DriveId)> GetSharepointDriveIds(GraphServiceClient gsc, List<Site> siteList)
{
    var siteDriveIds = new List<(string SiteId, string DriveId)>();
    int batchSize = 20;

    for (int i = 0; i < siteList.Count; i += batchSize)
    {
        var batchRequestContent = new BatchRequestContentCollection(gsc);
        var batchSites = siteList.Skip(i).Take(batchSize).ToList();

        foreach (var site in batchSites)
        {
            var requestInformation = gsc.Sites[site.Id].Drives.ToGetRequestInformation();

            var requestId = batchRequestContent.AddBatchRequestStepAsync(requestInformation).GetAwaiter().GetResult();
        }
        
        var batchResponseContent = gsc.Batch.PostAsync(batchRequestContent).GetAwaiter().GetResult();
        // I'm having error here
        var responses = batchResponseContent.GetResponsesAsync().GetAwaiter().GetResult();
    }

    return siteDriveIds;
}

Solution

  • The method GetResponsesAsync() is obsolete and throws NotImplementedException.

    The message for obsolete method suggests to use GetResponsesStatusCodesAsync and then GetResponseByIdAsync.

    private List<(string SiteId, string DriveId)> GetSharepointDriveIds(GraphServiceClient gsc, List<Site> siteList)
    {
        var siteDriveIds = new List<(string SiteId, string DriveId)>();
        int batchSize = 20;
    
        for (int i = 0; i < siteList.Count; i += batchSize)
        {
            var batchRequestContent = new BatchRequestContentCollection(gsc);
            var batchSites = siteList.Skip(i).Take(batchSize).ToList();
    
            foreach (var site in batchSites)
            {
                var requestInformation = gsc.Sites[site.Id].Drives.ToGetRequestInformation(rc=>
                {
                    rc.QueryParameters.Select = new string[] { "id" };
                    rc.QueryParameters.Expand = new string[] { "list($select=parentReference)" };
                });
    
                var requestId = batchRequestContent.AddBatchRequestStepAsync(requestInformation).GetAwaiter().GetResult();
            }
    
            var batchResponseContent = gsc.Batch.PostAsync(batchRequestContent).GetAwaiter().GetResult();
    
            var statusCodes = batchResponseContent.GetResponsesStatusCodesAsync().GetAwaiter().GetResult();
            foreach (var statusCode in statusCodes)
            {
                if (statusCode.Value == HttpStatusCode.OK)
                {
                    var drives = batchResponseContent.GetResponseByIdAsync<DriveCollectionResponse>(statusCode.Key).GetAwaiter().GetResult();
                    foreach (var drive in drives.Value)
                    {
                        siteDriveIds.Add((drive.List.ParentReference.SiteId, drive.Id));
                    }
                }
            }
        }
    
        return siteDriveIds;
    }
    

    GetResponsesStatusCodesAsync contains response status code for each request inside the batch. It helps you to distinguish if a particular request succeeded or not.

    I've modified ToGetRequestInformation to reduce the amount of data returned by the Graph API. You only need drive's id and site's id.