Search code examples
c#filemicrosoft-graph-apimicrosoft-graph-sdks

Why am I getting a null stream value when using file content from the Graph API?


I'm trying to get file stream, but every time it returns null. I use graph api to get files from documents folder on my site.

All this worked just a couple of days ago and suddenly stopped.

My permissions with Application type:

  • Sites.FullControll.All (and all permissions lower just in case)
  • Files.ReadWrite.All (for files only this)

This is how I try to get file stream:

 public async Task<Stream> GetFileStreamAsync(string filePath)
 {
     var driveId = await GetDriveId(_settings.Url, LIST_ID);
     var driveItem = await GetDriveItemAsync(filePath, driveId);
     try
     {
         var content = await _graphClient.Drives[driveId].Items[driveItem.Id].Content.GetAsync().ConfigureAwait(false);
         return !content.CanSeek ? null : content;
     }
     catch (ODataError ex)
     {
         _logService.Log("_SharepointService", $"Error on getting file stream with filePath: {filePath}:{ex.Error?.Message}");
     }

     return null;
 }

This is drive item:

 var driveItem = await _graphClient
     .Drives[driveId]
     .Root
     .ItemWithPath(Path.GetFileName(filePath)).GetAsync().ConfigureAwait(false);

This is drive Id:

 var siteId = await GetSiteId(url);
 var listDrive = await _graphClient
     .Sites[siteId]
     .Lists[listId]
     .Drive
     .GetAsync().ConfigureAwait(false)

This is site Id:

 var site = await _graphClient
     .Sites[$"{domainName}:"]
     .Sites[siteName]
     .GetAsync().ConfigureAwait(false)

And graph client:

 private GraphServiceClient GetGraphClientService()
 {
     var scopes = new[] { "https://graph.microsoft.com/.default" };
     var options = new TokenCredentialOptions
     {
         AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
         Retry = { Delay = TimeSpan.FromMinutes(40), MaxRetries = 3 }
     };

     var clientSecretCredential = new ClientSecretCredential(
         _settings.SpTenantId, _settings.ClientId, _settings.Secret, options);
     return new GraphServiceClient(clientSecretCredential, scopes);
 }

Solution

  • Try to buffer the stream from the response to a memory stream

    public async Task<Stream> GetFileStreamAsync(string filePath)
     {
         var driveId = await GetDriveId(_settings.Url, LIST_ID);
         var driveItem = await GetDriveItemAsync(filePath, driveId);
         try
         {
             var content = await _graphClient.Drives[driveId].Items[driveItem.Id].Content.GetAsync().ConfigureAwait(false);
             var bufferedMemoryStream = new MemoryStream();
             content.CopyTo(bufferedMemoryStream);
             return bufferedMemoryStream;
         }
         catch (ODataError ex)
         {
             _logService.Log("_SharepointService", $"Error on getting file stream with filePath: {filePath}:{ex.Error?.Message}");
         }
    
         return null;
     }