Downloading images from publicly shared folders and sub-folders on Dropbox - c#

This is similar to my previous question:
Downloading images from publicly shared folder on Dropbox
I have this piece of code (simplified version) that needs to download all images from publicly shared folder and all sub-folders.
using Dropbox.Api;
using Dropbox.Api.Files;
...
// AccessToken - get it from app console
// FolderToDownload - https://www.dropbox.com/sh/{unicorn_string}?dl=0
using (var dbx = new DropboxClient(_dropboxSettings.AccessToken))
{
var sharedLink = new SharedLink(_dropboxSettings.FolderToDownload);
var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink);
// var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink, recursive: true);
// "recursive: true" throws: Error in call to API function "files/list_folder": Recursive list folder is not supported for shared link.
foreach (var entry in sharedFiles.Entries)
{
if (entry.IsFile)
{
var link = await dbx.Sharing.GetSharedLinkFileAsync(url: _dropboxSettings.FolderToDownload, path: "/" + entry.Name);
var byteArray = await link.GetContentAsByteArrayAsync();
}
if (entry.IsFolder)
{
var subFolder = entry.AsFolder;
// var folderContent = await dbx.Files.ListFolderAsync(path: subFolder.Id);
// var subFolderSharedLink = new SharedLink(???);
}
}
}
How do I list entries of all sub-folders?

For any given subfolder, to list its contents, you'll need to call back to ListFolderAsync again, using the same sharedLink value, but supplying a path value for the subfolder, relative to the root folder for the shared link.
For example, if you list the contents of the folder shared link, and one of the entries is a folder with the name "SomeFolder", to then list the contents of "SomeFolder", you would need to make a call like:
await dbx.Files.ListFolderAsync(path: "/SomeFolder", sharedLink: sharedLink);

Related

C# - CSOM - Upload a file to a subdirectory in Sharepoint Online

I'm trying to upload a file to SharePoint Online and I got this sample code:
var uploadFile = list
.RootFolder
.Folders
.GetByPath(ResourcePath.FromDecodedUrl("A"))
.Files
.Add(newFile);
ctx.Load(uploadFile);
await ctx.ExecuteQueryAsync();
Which works perfectly fine, so everything around it works. But apparently this snippet
var uploadFile = list
.RootFolder
.Folders
.GetByPath(ResourcePath.FromDecodedUrl("A/B"))
.Files
.Add(newFile);
ctx.Load(uploadFile);
await ctx.ExecuteQueryAsync();
Throws System.IO.DirectoryNotFoundException even though both directories exist. So how can I upload a file to the subdirectory "B"?
Try to upload file like this:
public static void UploadFile(ClientContext context,string uploadFolderUrl, string uploadFilePath)
{
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.GetFileName(uploadFilePath)
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(uploadFolderUrl);
var uploadFile = targetFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
}
using (var ctx = new ClientContext(webUri))
{
ctx.Credentials = credentials;
UploadFile(ctx,"LibName/FolderName/Sub Folder Name/Sub Sub Folder Name/Sub Sub Sub Folder Name",filePath);
}
Please check out another similiar thread here:
Alternative Save/OpenBinaryDirect methods for CSOM for SharePoint Online

Open Local HTML files in Xamarin.Forms Web View NOT in Assets Folder

I am trying to open a multipage HTML web page (i.e. test.html, test.css and test.js) which has been downloaded dynamically (thefore can't use assets) and stored in the apps internal storage (Xamarin.Essentials.FileSystem.AppDataDirectory).
The URL I am trying to use is as follows:
file:///data/user/0/com.test/files/HTML/Test.html
However I just get file not found.
var filesToDownload = new string[] { "http://myserver/test/test.html", "http://myserver/test/test.css" };
var directory = System.IO.Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, "HTML");
if (System.IO.Directory.Exists(directory))
{
System.IO.Directory.Delete(directory, true);
}
System.IO.Directory.CreateDirectory(directory);
using (var wc = new System.Net.WebClient())
{
foreach (var f in filesToDownload)
{
wc.DownloadFile(f, System.IO.Path.Combine(directory, System.IO.Path.GetFileName(f)));
}
}
var source = new UrlWebViewSource
{
Url = System.IO.Path.Combine("file://" + directory, "Test.html")
};
WebView1.Source = source;
There are several points you have to make sure:
1 Add the Xamarin.Essentials NuGet package to each project
2 http://myserver/test/test.html and http://myserver/test/test.css are existed and accessible.
3 The file name of webview source should be the same with the file name you have written to your storage. Not Test.html, but test.html
So
Url = System.IO.Path.Combine("file://" + directory, "Test.html") should be modified to
Url = System.IO.Path.Combine("file://" + directory, "test.html")

Get all files inside a specific folder in a library with UWP

I'm trying to get all the videos in a specific folder inside the Videos library using UWP, right now I can get all videos inside the Videos library, but I'd like to reduce my results to only those inside the specified folder. My code is this:
Windows.Storage.Search.QueryOptions queryOption = new QueryOptions(CommonFileQuery.OrderByTitle, new string[] {".mp4"});
queryOption.FolderDepth = FolderDepth.Deep;
var files = await KnownFolders.VideosLibrary.CreateFileQueryWithOptions(queryOption).GetFilesAsync();
StorageFile videoToPlay = (files[new Random().Next(0, files.Count)] as StorageFile);
var stream = await videoToPlay.OpenAsync(Windows.Storage.FileAccessMode.Read);
Player.SetSource(stream, videoToPlay.ContentType);
Debug.WriteLine(Player.Source);
How could I access a subfolder named "Videos to Play" and then get all the videos inside that folder? I tried accesing it by using a path like:
string localfolder = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
var array = localfolder.Split('\\');
var username = array[2];
string[] allVideos = System.IO.Directory.GetFiles("C:/Users/" + username + "/Videos/Videos to Play");
But I get access denied even though I already requested access to the Videos library (and the fact that the first example works shows that I actually have access to it).
try
{
var folder = await KnownFolders.VideosLibrary.GetFolderAsync("Videos to Play");
}
catch (FileNotFoundException exc)
{
// TODO: Handle the case when the folder wasn't found on the user's machine.
}
In the folder variable you'll have the reference to the desired folder. Then it's the very same stuff that you already do, but instead of KnownFolders.VideosLibrary folder use this one!

How to upload a file in a Sharepoint library subfolder using c#?

I need to upload a file using c# console app in a sharepoint library. I manage to upload it to the parent library only. But the requirement is to upload it on its sub folder.
So here's the Folder Structure:
Root Folder
-Sub Folder 1
---Sub Folder 2
----Sub Folder 3
I need to upload it in Sub Folder 3. Right now, I'm only able to upload on the Root Folder.
It throws an error when I tried to input the Sub Folder 3 in the GetByTitle method, but when it's the root folder, it is succeeding to upload.
Here's my code.
using (ClientContext clientContext = new ClientContext(siteURL))
{
clientContext.Credentials = new System.Net.NetworkCredential(#"username", "password", "domain");
var web = clientContext.Web;
// Create the new file
var newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(#"C:\filepath\test.xlsx");
newFile.Overwrite = true;
newFile.Url = "Test Upload.xlsx";
List list = web.Lists.GetByTitle("Service Oriented Architecture (SOA)");
clientContext.Load(list);
clientContext.ExecuteQuery();
clientContext.Load(list.RootFolder);
clientContext.Load(list.RootFolder.Folders);
clientContext.ExecuteQuery();
foreach (Folder SubFolder in list.RootFolder.Folders)
{
if (SubFolder.Name.Equals("07 - SOA Environment"))
{
//What's next?
}
}
}
There are several options how to specify sub folder while uploading the file using CSOM
There are two assumptions about the provided solutions below:
The library name(url) is Documents and has the following folder structure:
Folder/Sub Folder/Sub Sub Folder/Sub Sub Sub Folder/
Folder structure already exists
Using FileCreationInformation.Url property
Use FileCreationInformation.Url property to specify the folder url for a uploaded file.
The following example demonstrates how to specify relative url (a slightly modified version of your example, the main difference comes in specifying FileCreationInformation.Url)
var uploadFilePath = #"c:\tmp\SharePoint User Guide.docx";
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.Combine("Documents/Folder/Sub Folder/Sub Sub Folder/Sub Sub Sub Folder/", Path.GetFileName(uploadFilePath))
};
var list = context.Web.Lists.GetByTitle("Root Folder");
var uploadFile = list.RootFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
Using Web.GetFolderByServerRelativeUrl method
Use Web.GetFolderByServerRelativeUrl method to retrieve a folder where file have to be uploaded:
public static void UploadFile(ClientContext context,string uploadFolderUrl, string uploadFilePath)
{
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.GetFileName(uploadFilePath)
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(uploadFolderUrl);
var uploadFile = targetFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
}
Usage
using (var ctx = new ClientContext(webUri))
{
ctx.Credentials = credentials;
UploadFile(ctx,"Documents/Folder/Sub Folder/Sub Sub Folder/Sub Sub Sub Folder",filePath);
}
You need to get sub folder within folder. like below
docs.RootFolder.SubFolders
Remaining things is same, just need to add in same folder.
try to go into folder like below
docs.Folders["FolderName"]

Why would GetFilesAsync return no files?

Why would GetFilesAsync return no files? I have a folder that contains images, no subfolders, and no other files. FolderPicker shows the expected folder content. However, GetFilesAsync(OrderByName) returns no items.
(The folder is not part of any library and is not indexed).
Edit - Add Code
Getting the folder:
var folder = await folderPicker.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
Accessing folder content:
var foldersFiles = await folder.GetFilesAsync(CommonFileQuery.OrderByName);
foldersFiles is empty. However, Windows Explorer and the folder picker show that it has content.
Edit - More info
This returns files. The only difference is the CommonFileQuery is removed.
var foldersFiles = await folder.GetFilesAsync();
Edit - More info
This also does not work:
var queryOptions = new QueryOptions(CommonFileQuery.OrderByName, null)
{
FolderDepth = FolderDepth.Deep
};
var query = folder.CreateFileQueryWithOptions(queryOptions);
var foldersFiles = await query.GetFilesAsync();
Remove CommonFileQuery.OrderByName, and it works.
My current work around is to avoid CommonFileQuery.OrderByName (...and maybe the other OrderBy's too).

Categories