I’m working on a C# application that downloads files from a SharePoint library using the Microsoft Graph API. The issue that the API returns null value object when I try to access the nested folder because the logged-in user only has access to a specific nested folder within the library.
If user has access on Document /Blackout(folder/ Then code is returning value. But If user has access only on Native Draft then value object is blank.
jsonDocument.RootElement.GetProperty("value").EnumerateArray()
public async Task<bool> DownloadDrive(CancellationToken cancellationToken)
{
OutputWindow.Info($"Start DownloadDrive.", _resultText);
string siteId = "XXXXXXXXXXXXXXXXXXXXXXXX";
string libraryUrl = "https://XXXXXX/sites/{sitename}/Shared%20Documents";
string driveId = await GetDriveId(siteId, libraryUrl);
if (string.IsNullOrEmpty(driveId))
{
OutputWindow.Info($"SharePoint Library under {libraryUrl} could not be found.", _resultText);
return false;
}
if (Directory.Exists(_localFolder))
{
Directory.Delete(_localFolder, true);
}
Directory.CreateDirectory(_localFolder);
await DownloadLibrary(driveId, _localFolder);
return true;
}
private async Task<string> GetDriveId(string siteId, string libraryUrl)
{
var requestUrl = $"https://graph.microsoft.com/v1.0/sites/{siteId}/drives";
var response = await _httpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var jsonDocument = JsonDocument.Parse(responseContent);
foreach (var drive in jsonDocument.RootElement.GetProperty("value").EnumerateArray())
{
if (drive.GetProperty("webUrl").GetString() == libraryUrl)
{
return drive.GetProperty("id").GetString();
}
}
return null;
}
private async Task DownloadLibrary(string driveId, string path)
{
var requestUrl = $"https://graph.microsoft.com/v1.0/drives/{driveId}/root/children";
var response = await _httpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var jsonDocument = JsonDocument.Parse(responseContent);
foreach (var driveItem in jsonDocument.RootElement.GetProperty("value").EnumerateArray())
{
await DownloadDriveItem(driveItem, driveId, path);
}
}
private async Task DownloadDriveItem(JsonElement driveItem, string driveId, string path)
{
string itemName = driveItem.GetProperty("name").GetString() ?? string.Empty;
OutputWindow.Info($"{itemName}", _resultText);
if (!driveItem.TryGetProperty("@microsoft.graph.downloadUrl", out var downloadUrl))
{
OutputWindow.Info($"Downloading the folder {driveItem.GetProperty("webUrl").GetString()}", _resultText);
var folderPath = System.IO.Path.Combine(path, driveItem.GetProperty("name").GetString());
Directory.CreateDirectory(folderPath);
var requestUrl = $"https://graph.microsoft.com/v1.0/drives/{driveId}/items/{driveItem.GetProperty("id").GetString()}/children";
var response = await _httpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var jsonDocument = JsonDocument.Parse(responseContent);
foreach (var childItem in jsonDocument.RootElement.GetProperty("value").EnumerateArray())
{
await DownloadDriveItem(childItem, driveId, folderPath);
}
}
else
{
OutputWindow.Info($"Downloading the file {driveItem.GetProperty("webUrl").GetString()}", _resultText);
var filePath = System.IO.Path.Combine(path, driveItem.GetProperty("name").GetString());
var fileResponse = await _httpClient.GetAsync(downloadUrl.GetString());
fileResponse.EnsureSuccessStatusCode();
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
await fileResponse.Content.CopyToAsync(fileStream);
}
}
5