Reputation: 682
I have been trying to leverage the Microsoft Graph Api to communicate with user's one drive business inside a MVC web app, have set up everything with delegated permissions and can read and write data in logged-in user's ODB fine however is there any way by which nested folder or directory structure can be created?
Currently I am using code below to create the folder in the root of user's ODB and works fine but looking for a way to create hierarchy of the folders when path is provided before uploading the file in it.
DriveItem rootDirectory = graphServiceClient.Me.Drive.Root.Children.Request().AddAsync(new DriveItem
{
Name = "RootDirectory",
Folder = new Folder(),
}).Result;
And for another folder inside RootDirectory trying this but does not seem to work (where rootDirectory is object created above)
DriveItem subDirectory = graphServiceClient.Me.Drive.Root.Children.Request().AddAsync(new DriveItem
{
Name = "SubDirectory",
Folder = rootDirectory.Folder
}).Result;
Even if it works with some fix, not sure if it is most optimal way to do it, suggestions will be appreciated.
Upvotes: 3
Views: 3098
Reputation: 614
I revisited the answer of Pic Mickael because it doesn't work for me (it just create two subfolders).
What I do is to create the first folder of my path so I have a start folder. If I don't do this, when I try to add the drive item with an empty path I get an error.
So, let's create a root folder, first:
private static void CreateRootFolder(GraphServiceClient gc, string rootFolder)
{
var root = gc
.Drives[_driveId]
.Root
.Children
.Request()
.AddAsync(new DriveItem()
{
Name = rootFolder,
Folder = new Microsoft.Graph.Folder(),
AdditionalData = new Dictionary<string, object>
{
{
"@microsoft.graph.conflictBehavior", "replace"
}
}
})
.Result;
}
When I have my first folder, I can loop through all the others:
private static void CreateSubFolders(GraphServiceClient gc, string rootFolder, string foldername)
{
string[] splitted = foldername.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
string pathCompleto = rootFolder;
foreach (string folder in splitted)
{
var driveItem = new DriveItem
{
Name = folder,
Folder = new Microsoft.Graph.Folder(),
AdditionalData = new Dictionary<string, object>
{
{
"@microsoft.graph.conflictBehavior", "replace"
}
}
};
var newFolder = gc
.Drives[_driveId]
.Root
.ItemWithPath(pathCompleto)
.Children
.Request()
.AddAsync(driveItem)
.Result;
pathCompleto = string.Format("{0}{1}{2}", pathCompleto, string.IsNullOrEmpty(pathCompleto) ? "" : "/", folder);
}
In the main program I will have two calls like this:
CreateRootFolder(_graphClient, "Folder00");
CreateSubFolders(_graphClient, "Folder00", "FolderAA/FolderBB/FolderCC/FolderDD/FolderEE");
This could be improved, but in my case it nicely resolve the problem.
Upvotes: 0
Reputation: 1274
I made a small function to do that.
While it is true that the use of try-catch is not the best practice, in the end I think it is better than polling each folder recursively for its children, then lookup by name if part of the path is there.
public async Task CreateFolder(string foldername)
{
string[] splitted = foldername.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
var f = graphServiceClient.Me.Drive.Root;
string p = "";
IDriveItemRequestBuilder b;
DriveItem driveItem;
foreach (string folder in splitted)
{
p = string.Format("{0}{1}{2}", p, string.IsNullOrEmpty(p) ? "" : "/", folder);
b = graphServiceClient.Me.Drive.Root.ItemWithPath(p);
try
{
driveItem = await b.Request().GetAsync();
}
catch
{
driveItem = null;
}
if (driveItem == null)
{
var f2 = await f.Children.Request().AddAsync(new DriveItem()
{
Name = folder,
Folder = new Folder()
});
b = graphServiceClient.Me.Drive.Root.ItemWithPath(p);
}
f = b;
}
}
and you call is like this:
await CreateFolder("folder1/folder2/folder3");
Upvotes: 4
Reputation: 24569
but looking for a way to create hierarchy of the folders when path is provided before uploading the file in it.
Based on my experience hierarchy of the folders
is not supported by graphServiceClient currently.
If want to create a sub folder, it requires that parent folder is exist.
As a workaround, we could create the sub folder with following code. You also create a recursive function to create the nested function
var folder= graphserviceClient.Me.Drive.Root.Children.Request()
.AddAsync(new DriveItem
{
Name = "tomfolder",
Folder = new Folder()
}).Result;
var subfolder = graphserviceClient.Me.Drive.Items[folder.Id].Children.Request()
.AddAsync(new DriveItem
{
Name = "subfolder",
Folder = new Folder()}
).Result;
And you also could give your good ideas to azure team.
Upvotes: 2