Search code examples
c#azuremicrosoft-graph-apionedrive

How to list shared folders?


I want to list the shared folders in a user's OneDrive. I therefore followed the docs and called

var sharedWithMeResponse = await client.Drives[driveId].SharedWithMe.GetAsSharedWithMeGetResponseAsync();

Unfortunately this gives an exception "Invalid request". I have requested scopes

{
    "https://graph.microsoft.com/Files.ReadWrite",
    "https://graph.microsoft.com/Files.ReadWrite.All"
}

I don't see what could be wrong compared to the documentation. Can you point me to it?

Thanks @Sridevi for asking for error details. Here they are. I now see that there is a "400" response which seems to indicate permission issues. (Weirdly, until few months ago with the old SDK version, I didn't have such problems.)

The Authentication is performed like

var _publicClientApp = PublicClientApplicationBuilder.Create(ClientID)
    .WithRedirectUri($"msal{ClientID}://auth")
    .Build();
...

var scopes = new List<string>
                    {
                        "https://graph.microsoft.com/Files.ReadWrite",
                        "https://graph.microsoft.com/Files.ReadWrite.All"
                    };

AuthenticationResult authenticationResult = await _publicClientApp.AcquireTokenInteractive(scopes)
    .WithParentActivityOrWindow((Activity)activity)
    .ExecuteAsync();
var authenticationProvider = new BaseBearerTokenAuthenticationProvider(new TokenFromAuthResultProvider() { AuthenticationResult = authenticationResult });
var client = new GraphServiceClient(new HttpClient(), authenticationProvider);

//this client is then used for the call which fails:
var sharedWithMeResponse = await client.Drives[driveId].SharedWithMe.GetAsSharedWithMeGetResponseAsync();

which uses

 public class TokenFromAuthResultProvider : IAccessTokenProvider
 {
     public AuthenticationResult AuthenticationResult
     {
         get;
         set;
     }
     public async Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object>? additionalAuthenticationContext = null,
         CancellationToken cancellationToken = new CancellationToken())
     {
         return AuthenticationResult.AccessToken;
     }

     public AllowedHostsValidator AllowedHostsValidator { get; }
 }

All of this code is part of an Android app using .net8 (https://github.com/PhilippC/keepass2android/blob/update-onedrive-implementation/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs).

exception screenshot 1

exception screenshot 2

exception screenshot 3


Solution

  • I have below file in Shared folder of my OneDrive account:

    enter image description here

    To get these details via Microsoft Graph API, I ran below API call in Graph Explorer:

    GET https://graph.microsoft.com/v1.0/me/drive/sharedWithMe
    

    Response:

    enter image description here

    To fetch the same details via c#, you need user's OneDrive ID that can be found with below API call:

    GET https://graph.microsoft.com/v1.0/me/drive/
    

    Response:

    enter image description here

    In my case, I ran below c# code that uses interactive flow to connect with Microsoft Graph and fetched shared files in response:

    using Azure.Identity;
    using Microsoft.Graph;
    using Microsoft.Graph.Models.ODataErrors;
    
    class Program
    {
        static async Task Main(string[] args)
        {
            var tenantId = "tenantId";
            var clientId = "appId";
    
            var scopes = new[] { "https://graph.microsoft.com/Files.ReadWrite",
        "https://graph.microsoft.com/Files.ReadWrite.All" }; 
            var interactiveCredential = new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions
            {
                TenantId = tenantId,
                ClientId = clientId,
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                RedirectUri = new Uri("http://localhost") //Use your redirect URI
            });
    
            var graphClient = new GraphServiceClient(interactiveCredential, scopes);
    
            var driveId = "OneDriveId";
    
            try
            {
                var result = await graphClient.Drives[driveId].SharedWithMe.GetAsSharedWithMeGetResponseAsync();
    
                if (result?.Value != null && result.Value.Count > 0)
                {
                    foreach (var item in result.Value)
                    {
                        Console.WriteLine($"Name: {item.Name}");
                        Console.WriteLine($"ID: {item.Id}");
                        Console.WriteLine($"Web URL: {item.WebUrl}");
                        Console.WriteLine($"Last Modified: {item.LastModifiedDateTime}");
                        Console.WriteLine(new string('-', 40));
                    }
                }
                else
                {
                    Console.WriteLine("No shared items found.");
                }
            }
            catch (ODataError odataError)
            {
                Console.WriteLine($"Error Code: {odataError.Error?.Code}");
                Console.WriteLine($"Error Message: {odataError.Error?.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception: {ex.Message}");
            }
        }
    }
    

    Response:

    enter image description here