Use C# CSOM ClientContext to download file from SharePoint document library or OneDrive for Business

This post will show how to download a file from any document library.


Using SharePoint SDK in Windows Phone 8 and the ISF (Isolated File Storage):

The steps:

  1. Get the relative url of the file
  2. Use the ClientContext object to download the file to the ISF
  3. Open the file in the phones office apps

The code:

Assuming you have the Item object:

string fileRef =

Stream inputStream;

private void BMSStackPanel_Tap(object sender, System.Windows.Input.GestureEventArgs e)


loadingProgressBar.IsVisible = true;

//get the relative url of the file

string fileRef = item[“FileRef”].ToString();

//get just the filename part

string fileName = fileRef.Substring(fileRef.LastIndexOf(“/”)+1);


Microsoft.SharePoint.Client.File.OpenBinaryDirect(Context, fileRef,

(object eventSender, OpenBinarySucceededEventArgs eventArgs) =>


if (eventArgs.Stream != null)

inputStream = eventArgs.Stream; //instantiating stream using the sharepoint file stream

Deployment.Current.Dispatcher.BeginInvoke(() =>


using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())


//create a local file with the same name using the input stream and saving through the output stream

using (IsolatedStorageFileStream outputStream = ISF.CreateFile(fileName))




byte[] bytes = new byte[inputStream.Length];

inputStream.Read(bytes, 0, (int)inputStream.Length);

outputStream.Write(bytes, 0, bytes.Length);




catch (Exception ex2)




loadingProgressBar.IsVisible = false;






}, null); //im passing null for the failed event. this should be handled properly though


private async void LaunchFile(string fileName)


var file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);

await Windows.System.Launcher.LaunchFileAsync(file);




Using Client OM in C#:

Assuming you have the Item object:

//get the URL of the file you want:

var fileRef = item[“FileRef”];

//get the file contents:

FileInformation fileInfo = File.OpenBinaryDirect(context, fileRef.ToString());

using (var memory = new MemoryStream()) {

byte[] buffer = new byte[1024 * 64];

int nread = 0;

while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0) {

memory.Write(buffer, 0, nread);


memory.Seek(0, SeekOrigin.Begin);

// … here you have the contents of your file in memory,

// do whatever you want



In JavaScript:

  1. Globally declare the content and web objects as shown below.

    var context = SP.ClientContext.get_current(); //gets the current context

  2. var web = context.get_web(); //gets the web object

Now write the function to read a file in a Document Library.
function readFile() {


context.executeQueryAsync(OnreadServerRelativeURL, readFileFailure);


function OnreadServerRelativeURL() {

var fileUrl = web.get_serverRelativeUrl() + “/MyLibrary/MyTextFile.txt”;


url: fileUrl,

type: “GET”


.done(Function.createDelegate(this, readFileSuccess))

.error(Function.createDelegate(this, readFileFailure));


function readFileSuccess(data) {

//do whatever you need to with the data



function readFileFailure(sender, args) {


alert(‘Failed to read a file. Error:’ + args.get_message());



Use CSOM ClientContext to fetch documents from users personal OneDrive for Business

Say I want to provide the user a list of their personal files in their OneDrive for Business site – this is how to do it.  Note: this is for OneDrive for Business, not the standard OneDrive – for that see this article.

In essence each users personal files are in their own site collection. So we need to get the web url. You can see what the web url should be by browsing to your own OneDrive in the browser.  In my example Im going to use:

So that makes sense but what we actually need is the users own personal url, not mine.  For this we need to get the current user object then fetch their email address.  Replace any periods and @ symbols characters with underscores.  For this we can use the main tenant url as we dont current know what the personal site collection url is:

ClientContext  Context = new ClientContext(;​

Authenticator at = new Authenticator();

at.CookieCachingEnabled = true;

Context.Credentials = at;

web = Context.Web;


currentUser = web.CurrentUser;



string email = currentUserEmail;


The code above has been changed a bit from the actual to make it a bit clearer but you should get the idea of whats going on. Also its for windows phone 8 app, for a sharepoint you wont need to worry about the authentication.

OK, now that we have the email address we need to replace the characters to make it the same as users personal folder url:

email = email.Replace(“.”, “_”).Replace(“@”, “_”);


Next we get a ClientContext to the users personal site collection of:”+email+”/”);

Once we have that we need to access the Documents library. We do this jus the same way we would with any other document library and there are hundreds of articles online showing how to query list and libraries.

Link to create new documents in Office Online and OneDrive – WOPIFRAME

You can create hyperlinks to the create new document functionality in office online using the following URL structure and template type parameter:



Excel: Same with TemplateType=2

Powerpoint: Same with TemplateType=3

Onenote: Same with TemplateType=4


The folder/url doesnt have to be pointed at the users onedrive. it could be any folder on any site.


Took a while finding this. Leave  a comment if you found this useful!

Auto provision OneDrive for users – programmatically

By default OneDrive storage is not provisions for users until they click on the OneDrive link at the top navigation bar in Office 365.

This can be a massive pain, especially if they’re using the iPad app which wont provision OneDrive instead it just repeatedly asks them to login! Ouch!

Fortunately there is a way to do this using CSOM. Firstly download the client runtime dlls from ​

After installing, add the version 16 DLLs to a new c# console application in Visual Studio 2013 references from Program files/SharePoint Client Components.

Add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.UserProfiles;

namespace CreatePersonalSiteBulkConsole
class Program
static void Main(string[] args)
string userName = “”;
string passwordStr = “password”;
string serverUrl = “”;

using (var clientContext = new ClientContext(serverUrl))
SecureString password = new SecureString();
Array.ForEach(passwordStr.ToCharArray(), c => password.AppendChar(c));

var credentials = new SharePointOnlineCredentials(userName, password);

clientContext.Credentials = credentials;

var web = clientContext.Web;
ProfileLoader loader = ProfileLoader.GetProfileLoader(clientContext);

if (loader == null)
throw new InvalidOperationException(“Failed to get ProfileLoader”);

string[] userEmails = { “”, “” };