Hasan Othman
Hasan Othman

Reputation: 78

Create a Folder in Specific Directory in Sharepoint Drive using Graph SDK

how to make this real using just a given Url and whether it's possible or not, idk?

what i am trying to do :

Creating Folder in specific place in the Drive according to a String..
this String consist from 3 parts (every part represents folder easy!) for instance, mystring = "Analyse_General_Theory" , the path in Drive should be like : Analyse/General/Theory

so :

my Imagination to Solution would be like that :)

passing my stringUrl to Build Request then Posting my Folder

stringUrl = "https://CompanyDomin.sharepoint.com/sites/mySite/SharedFolders/Analyse/General/Theory"

then

await graphClient.Request(stringUrl).PostAsync(myLastFolder) !!! 

so that would be the result !

Analyse/General/Theory/myLastFolder

is there somethig like that ? or maybe similar to this Approach ?

Upvotes: 3

Views: 11955

Answers (2)

Matt
Matt

Reputation: 11

Unless I am missing something, I believe there have been changes to the Graph SDK which means that Jim Xu's answer no longer works.

I have been able to implement this with the below functions. Note that I haven't built any error handling for this.

This presupposes that

  1. You have the graphClient setup (and it has appropriate API permissions) and

  2. You have the SharePoint Site ID as a Guid.

    async internal Task<string> CreateSharePointFolder(Guid siteId, string documentLibraryName, string parentFolderPath, string folderName)
    {
        DriveCollectionResponse siteDrives = await graphClient.Sites[siteId.ToString()].Drives.GetAsync(); // Drives API doesn't support filtering
    
        string driveId = siteDrives.Value.Where(drive => drive.Name == documentLibraryName).First().Id; // Drives API doesn't support filtering
        DriveItem rootDriveItem = await graphClient.Drives[driveId].Root.GetAsync();
    
        string[] folderNames = parentFolderPath.Split('/');
        string driveItemId;
        driveItemId = await GetChildDriveItemId(driveId, rootDriveItem.Id, folderNames[0]);
    
        for (int i = 1; i < folderNames.Length; i++) driveItemId = await GetChildDriveItemId(driveId, driveItemId, folderNames[i]);
    
        var driveItemToCreate = new DriveItem
        {
            Name = folderName,
            Folder = new Folder
            {
            },
            AdditionalData = new Dictionary<string, object>
            {
                {
                    "@microsoft.graph.conflictBehavior" , "rename"
                },
            },
        };
        var response = await graphClient.Drives[driveId].Items[driveItemId].Children.PostAsync(driveItemToCreate);
        return response.Id;
    }
    
    async internal Task<string> GetChildDriveItemId(string driveId, string driveItemId, string childDriveItemName)
    {
        var driveItemChildren = await graphClient.Drives[driveId].Items[driveItemId].Children.GetAsync();
        var childDriveItemId = driveItemChildren.Value.Where(driveItem => driveItem.Name == childDriveItemName).First().Id; // DriveItem Children API doesn't support filtering
    
        return childDriveItemId;
    }
    

To get the SharePoint Site ID, I have the following implementation

async internal Task<Guid> GetSharePointSiteId(string hostName, string sitePath)
{
    var siteCollection = await graphClient.Sites.GetAllSites.GetAsGetAllSitesGetResponseAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Filter = $"webUrl eq 'https://{hostName}/{sitePath}'";
        requestConfiguration.QueryParameters.Select = new string[] {"webUrl", "sharepointIds"};
    });

    return Guid.Parse(siteCollection.Value.First().SharepointIds.SiteId);
}

where

  • hostName is of the format {domain}.sharepoint.com
  • sitePath is of the format sites/{siteName}

Upvotes: 1

Jim Xu
Jim Xu

Reputation: 23111

If you want to use Graph API to create a folder in SharePoint, please use the following Microsoft graph Rest API. Because Azure AD graph API just can be used to manage Azure AD resources (such as user, group, etc) and cannot be used to manage SharePoint resources. If we want to manage SharePoint resources with Graph API, we need to use Microsoft Graph API

POST https://graph.microsoft.com/v1.0/sites/{site-id}/drive/items/{parent-item-id}/children

For example

POST https://graph.microsoft.com/v1.0/sites/CompanyDomin.sharepoint.com/drive/items/root:/
{folder path}:/children

{
  "name": "<the new folder name>",
  "folder": { },
  "@microsoft.graph.conflictBehavior": "rename"
}

Regarding how to implement it with SDK, please refer to the steps are as below

  1. Register Azure AD application

  2. Create a client secret.

  3. Add API permissions for the application. Please add Application permissions : Files.ReadWrite.All and Sites.ReadWrite.All.

  4. Code. I use Client credential flow.

/* please run the following command install sdk Microsoft.Graph and Microsoft.Graph.Auth 

   Install-Package Microsoft.Graph
   Install-Package Microsoft.Graph.Auth -IncludePrerelease

*/

 string clientId = "<your AD app client id>";
            string clientSecret = "<your AD app client secret>";
            string tenantId = "<your AD tenant domain>";
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                        .Create(clientId)
                        .WithTenantId(tenantId)
                        .WithClientSecret(clientSecret)
                        .Build();

            ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
            GraphServiceClient graphClient = new GraphServiceClient(authProvider);
            var item = new DriveItem
            {

                Name = "myLastFolder",
                Folder= new Folder { },
                AdditionalData = new Dictionary<string, object>()
                    {
                        {"@microsoft.graph.conflictBehavior","rename"}
                    }
            };
            var r = await graphClient.Sites["<CompanyDomin>.sharepoint.com"].Drive.Items["root:/Analyse/General/Theory:"].Children.Request().AddAsync(item);
            Console.WriteLine("the folder name : " + r.Name);

enter image description here

Upvotes: 8

Related Questions