How to download files from OneDrive - c#

I am looking to download my files in public folder from One Drive, but it doesn't download the files.
Here is the scenario:
In public folder I have another folder with multiple files in it and is accessible widely.
for test purpose I have shared all the files in public folder (I don't if it's proper way of sharing it).
The following links are provided for me to download the file:
From shared folder link https://onedrive.live.com/redir?resid=DBBC281099F4FE69!646&authkey=!AGRCGuw8Y2_p9mA&ithint=folder%2c.mp3
From public folder link https://onedrive.live.com/redir?resid=DBBC281099F4FE69%21646
Direct link http://1drv.ms/1z9XlW6 -
I am using BackgroundTransferRequest to download the file using below code:
string filePathToDownload = string.Empty, fileName = "111.mp3";
filePathToDownload = "http://1drv.ms/1z9XlW6";
Uri transferUri = new Uri(Uri.EscapeUriString(filePathToDownload), UriKind.RelativeOrAbsolute);
BackgroundTransferRequest transferRequest = new BackgroundTransferRequest(transferUri);
transferRequest.Method = "GET";
transferRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
Uri downloadUri = new Uri(DataSource.TEMPDOWNLOADLOCATION + fileName, UriKind.RelativeOrAbsolute);
transferRequest.DownloadLocation = downloadUri;
transferRequest.Tag = fileName;
The file is 300Kb, but this only downloads 6 Kb.
How can I directly download the file from the links above (any of them)?
thanks!

If you replace the word redir with download in the url you get the raw file instead of the webpage i.e.
https://onedrive.live.com/download?resid=DBBC281099F4FE69%21646

Basically, you can't. Those links are links to the web content that shows the files you have shared. If your scenario doesn't mind asking the user to log in to OneDrive, then you can use the Live SDK to access these files.
To access your public folder from Live SDK, you need to either use Live SDK to get the folder-id for your public folder, or convert the IDs in the URL you copied into the format the Live SDK uses:
folder.<user-id>.<folder-resid>
Where is the part of before the !. In general you shouldn't construct an ID, since it's possible the IDs will change in the future, and instead you should retrieve the ID from the service. However, with the URL you pasted the ID would be:
folder.DBBC281099F4FE69.DBBC281099F4FE69!646
Which will allow you to call
https://apis.live.net:443/v5.0/folder.DBBC281099F4FE69.DBBC281099F4FE69!646/files?access_token=<valid_token>
and retrieve the IDs for the individual files, which you can then download via Live SDK following these details: http://msdn.microsoft.com/en-US/library/dn659726.aspx#download_a_file

For those who are still looking for a response to that question.
The easiest way to find the file path is to go to One Drive on the web and right-click on the file that we want and select Embed. Ξ€hen on the right we see the info window to integrate our file into a page. Inside the iframe is the source of the file. Then we have to replace the word embed with the word download and that's it.

Try something like this
//we first need the file id
string id = string.Empty;
//we need to get all of the filenames stored in the root of the skydrive account
LiveOperationResult result = await this.client.GetAsync("me/skydrive/files");
//lets make a list of all these filenames
List<object> items = result.Result["data"] as List<object>;
//for every filename, check if it is what we want, in this case "sample.txt"
//if it is what we want, get the id and save it to out already defined id value
foreach (object item in items)
{
IDictionary<string, object> file = item as IDictionary<string, object>;
if (file["name"].ToString() == "sample.txt")
{
id = file["id"].ToString();
}
}
//to download the file we need to use the id + "/content"
LiveDownloadOperationResult result2 = await client.DownloadAsync(string.Format("{0}/content", id));
//once the file had downloaded, lets copy it to IsolatedStorage
Stream stream = result2.Stream;
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileToSave = storage.OpenFile("sample.txt", FileMode.Create, FileAccess.ReadWrite))
{
stream.CopyTo(fileToSave);
stream.Flush();
stream.Close();
}
}
here client is the object of LiveConnectClient class.
Import
using Microsoft.Live;
using Microsoft.Live.Controls;
Here is use txt file as an example. Go through this example:http://www.baileystein.com/2013/10/20/skydrive-how-to-upload-and-download-a-text-file-on-wp8/

Related

Downloading images from publicly shared folder on Dropbox

I received a link to shared folder from e-commerce company. The link is public and not shared with my dropbox account directly.
How do I get an url to the image that I can pass to either DownloadAsync method of the same sdk or simply HttpClient and well ... download it?
Ideally it would be the same link I get when I click on the image when viewing that shared folder in a browser.
https://www.dropbox.com/sh/{folder_hash}/{file_hash_maybe}/{filename}?dl=0
This is what I have tried:
using Dropbox.Api;
using Dropbox.Api.Files;
...
var accessToken = "abracadabra";
var sharedFolderUrl = "https://www.dropbox.com/sh/{folder_hash}?dl=0";
using (var dbx = new DropboxClient(accessToken))
{
var sharedLink = new SharedLink(sharedFolderUrl);
var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink);
// sharedFiles - has over 13,000 entries, I use cursor to get them all.
foreach (var file in sharedFiles.Entries)
{
if (file.IsFile)
{
// tried this, but:
// 1. it's crazy to loop through all
// 2. link.Response.Url gives me the same url to a shared folder for all items
var link = await dbx.Sharing.GetSharedLinkFileAsync(url: sharedFolderUrl, path: "/" + file.Name);
}
}
}
Using the GetSharedLinkFileAsync method is the right way to programmatically download a file from a shared link. It actually gives both the metadata (in the link.Response in your code like you mentioned), as well as the file data directly (not via a URL).
To access the file data, you can use any of the GetContentAs... methods documented under IDownloadResponse as returned by GetSharedLinkFileAsync. In your code, that would look something like: link.GetContentAsStreamAsync() (or whichever one you want).
Alternatively, if you want to download the entire folder from the shared link, you can use the URL parameters documented in this help center article. (That may fail for very large folders though.)

Download and Delete files and folders based on criteria

I am working on Document Management System in ASP.NET using C#. I store all folders and files on a windows server and save folder and file info in SQL database as well. Everytime, I create a folder or file on server, I append the name with unique id from database. Example: contact~432cace7-a39c-4db5-a38f-9efe5d289bbf.pdf
Now we have different users who have access to same folders and need a way to delete and download based on their access.
Example: I have 2 users, user-1 and user-2. I have a folder-1 which contains 2 files. file-1 is uploaded by user-1 and file-2 by user-2. Now when user-1 views the file in browser page, I show folder-1 and within that file-1 based on database query. But if user one selects folder-1 for download, it will go to the windows server and download both file-1 and file-2 as physically they are within same folder on server. Same is the case with delete too.
How can I handle this scenario?
Basically, handling in SQL is much easy with relational database but I am thinking how can this be done on windows server efficiently?
My Idea: Call a DB stored proc that returns list of ids and based on that generate the download zip or delete. But since there can be nesting of folder and files, how efficient will this be in performance?
Follow the code below and process :
In Js File :
var file_name = response.value[0]["name"];
var downloadurl = response.value[0]"#microsoft.graph.downloadUrl"];
//-----------------------------------------------------------------------//
function HandleIT(downloadurl,file_name) {
PageMethods.ProcessIT(downloadurl,file_name, onSucess, onError);
function onSucess(result) {
alert(result);
}
function onError(result) {
alert('Something wrong.');
}
}
In Code Behind us the Webmethod :
[WebMethod]
public static string ProcessIT(string downloadURL, string file_name)
{
// Create a new WebClient instance.
WebClient myWebClient = new WebClient();
string path = #"c:\";
string path_n_name = path + file_name;
// Download the Web resource and save it into the current filesystem folder.
myWebClient.DownloadFile(downloadURL, path_n_name);
return "SUCCESS";
}
This is how I delete files
if(fileName != null || fileName != string.empty)
{
if((System.IO.File.Exists(fileName))
System.IO.File.Delete(fileName);
}
Hope it works for you...!

Saving file on documents library Windows 8 C#

I'm creating a simple app for windows 8 that writes me a xml file to documents library.
The problem is when i'm save the file, it saves it on skydrive and i want to save it on c:\Users\pc-name\Documents. I'm using KnownFolders.DocumentsLibrary and updated the manifest to save xml files too, otherwise i couldn't save any file in it.
public static async void XmlSaveFreeChallenge(Challenge currentChallenge)
{
var challenge = new XElement("Challenge");
var docSave = new XDocument(challenge);
challenge.Add(new XAttribute("Name", currentChallenge.Template));
var pontos = new XElement("Type", currentChallenge.Type);
docSave.Descendants("Challenge").FirstOrDefault().Add(pontos);
var folder = KnownFolders.DocumentsLibrary;
var outputStream = await folder.OpenStreamForWriteAsync("CaiMUfiles\\output\\Desafios\\" + currentChallenge.Template + ".xml", CreationCollisionOption.ReplaceExisting);
var ms = new MemoryStream();
docSave.Save(outputStream, SaveOptions.None);
await ms.CopyToAsync(outputStream);
}
The user gets to choose where the Documents library points. See the following option: settings charm -> Change PC Settings -> SkyDrive -> Save documents to SkyDrive by default
I'm not sure if it's possible for your app to override the user's choice there. Even if it is possible, it's probably better to respect the user's choice.
What Isaac McGarvey said is correct nevertheless there might by something that you can do. i did not found a way how to programmatically switch default saving folder for libraries but you still have access to all folders that is included in libraries. The only think is that you need to know absolute path so if you can save the path before then you can use this to get desired folder :
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync("AbsolutePath");
and then you can start enumerating creating or whatever you need. The problem is that if you use for example
List<StorageFolder> folder = await KnownFolders.DocumentsLibrary.GetFoldersAsync();
you wont get folder for Documents and folder for SkyDrive and folder for other linked folders to libraries you will just get all folders that is inside all of these folders in one list which mean you cannot choose where to save file.
I hope this helps a bit.

Using FileUpload C#

I have a project where I get a list of file location strings that I want to save locally. I want to use a FileUploader to do so. I am trying something like this so far:
FileUpload filesaver = new FileUpload();
//Iterate over each files (InputFiles is a linked list of file locations)
foreach (string File in InputFiles)
{
//Get file
Stream fileLoaded = OpenFile(File);
filesaver.FileContent = fileLoaded;
//Save file
filesaver.SaveAs(DownloadLocation);
//Code...}
The problem is that filesaver.FileContent = fileLoaded; is not a valid call (FileContent is read only).
How would I be able to get the file to the file loader so that I can save it if I have a string of that file location?
Edit I am using the FileUpload Class
The ASP.NET FileUploader has the client side send the file to the server side. It does not send a file path as a string, so there is no way to intercept the file path and "upload" on the server side. if that is your intent, you are not going to find a way to get there from here.
If you want to save the actual file binary bits once it gets to the server, there are plenty of examples out there that persist the data to databases or file system.
If you are trying to get paths as strings, the file uploader is not your best choice, but note that the file path strings, if they are local to the client, are of no use on the server side.
You can just use:
If (filesaver.HasFile)
{
filesaver.SaveAs("C:\YourFilePath\" & filesaver.FileName);
}

Visual Studio 2010 working directory

I'm developing a C# asp.net web application. I'm basically done with it, but I have this little problem. I want to save xml files to the "Users" folder within my project, but if I don't psychically hard code the path "C:......\Users" in my project it wants to save the file in this "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\Users" folder, this is an annoying problem because I can't use the hard coded directory on our web hosts server. Also, I have a checkbox list that populates from the the "DownloadLibrary" folder in my project, and its suppose to download the files from that fold but its also looking to the "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" folder for download even though its populating from the correct folder. I'm very confused by this, its the first time something like this has ever happened to me. Can anyone please help me with this, its the only thing standing in my way to complete this project.
You don't want to use the working directory at all; you want to use a directory relative to where the web application is located (which can be retrieved from HttpRequest.ApplicationPath.
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string pathToApp = request.MapPath(request.ApplicationPath);
string usersPath = System.IO.Path.Combine(pathToApp, "Users");
Update
As VincayC points out; asp.net development is not my strongest skill ;) The above code is essentially equivalent of this (much simpler) code:
string usersPath = HttpRequest.Current.Request.MapPath("~/Users");
If this code appears in the code-behind of a page, you can probably cut HttpContext.Current as well, since the page has a Request property.
That did fix the one problem I'm having, but the downloads are still not downloading from the right place, the program still wants to get the files from "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" directory here is the code I'm using
--Code to populate the checkbox--
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string appPath = request.MapPath(request.ApplicationPath);
string directory = System.IO.Path.Combine(appPath, "DownloadLibrary/");
// Get the list of files into the CheckBoxList
var dirInfo = new DirectoryInfo(directory);
cblFiles.DataSource = dirInfo.GetFiles();
cblFiles.DataBind();
--Download Button Code--
// Tell the browser we're sending a ZIP file!
var downloadFileName = string.Format("Items-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HH_mm_ss"));
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", "filename=" + downloadFileName);
// Zip the contents of the selected files
using (var zip = new ZipFile())
{
// Add the password protection, if specified
/*if (!string.IsNullOrEmpty(txtZIPPassword.Text))
{
zip.Password = txtZIPPassword.Text;
// 'This encryption is weak! Please see http://cheeso.members.winisp.net/DotNetZipHelp/html/24077057-63cb-ac7e-6be5-697fe9ce37d6.htm for more details
zip.Encryption = EncryptionAlgorithm.WinZipAes128;
}*/
// Construct the contents of the README.txt file that will be included in this ZIP
var readMeMessage = string.Format("Your ZIP file {0} contains the following files:{1}{1}", downloadFileName, Environment.NewLine);
// Add the checked files to the ZIP
foreach (ListItem li in cblFiles.Items)
if (li.Selected)
{
// Record the file that was included in readMeMessage
readMeMessage += string.Concat("\t* ", li.Text, Environment.NewLine);
// Now add the file to the ZIP (use a value of "" as the second parameter to put the files in the "root" folder)
zip.AddFile(li.Value, "Your Files");
}
// Add the README.txt file to the ZIP
//zip.AddEntry("README.txt", readMeMessage, Encoding.ASCII);
// Send the contents of the ZIP back to the output stream
zip.Save(Response.OutputStream);</pre></code>
I'm not sure how to get the downloads to point to my application directory,I tried everything I can think off.

Categories

Resources