Provider Hosted App – Upload Large Files using CSOM

We all at some time struggled with uploading large files using CSOM in O365. Using managed client object model, we can upload a maximum of 2MB file size. If the file is of larger size, we usually had two options:

  1. File.SaveBinaryDirect
  2. Using REST which supports upto 2GB

The first option can not be used in Sharepoint Online because SaveBinaryDirect does not work with claims authentication (check this link).

Update: We can now use SaveBinaryDirect in SP Online by using SharePointOnlineCredentials class which could be used for authentication of context but I am yet not able to make it work in provider hosted add-in. It works in normal console app by providing credentials though.

Does that mean we are left with REST only? Actually NO. We have one more way by which we can upload files greater than 2MB in O365 using CSOM in provider hosted app. But let’s first see the standard CSOM way which allows us 2MB file upload.


var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext, SPHostUrl);
using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
{
if (clientContext != null)
{
//code for file size < 2MB
//file is the input which we uploaded. It can be taken from Request.Files
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(file.FileName);
newFile.Url = Path.GetFileName(file.FileName);
List docs = clientContext.Web.Lists.GetByTitle("List_Name");
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
clientContext.Load(uploadFile);
clientContext.ExecuteQuery();
}
}

view raw

uploadfile.cs

hosted with ❤ by GitHub

Now the method to upload larger files is exactly the same. We only have to use FileCreationInformation.ContentStream property instead of FileCreationInformation.Content property. The whole code is present below:


var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext, SPHostUrl);
using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
{
if (clientContext != null)
{
//file is uploaded file. Could be read from Request.Files
using (FileStream fs = new FileStream(file.FileName, FileMode.Open))
{
//code for file size > 2MB. tested upto 50MB
FileCreationInformation newFile = new FileCreationInformation();
newFile.ContentStream = fs;
newFile.Url = Path.GetFileName(file.FileName);
newFile.Overwrite = true;
List docs = clientContext.Web.Lists.GetByTitle("List_Name");
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
clientContext.Load(uploadFile);
clientContext.ExecuteQuery();
}
}
}

In some cases, you might get a FileNotFoundException while using above code. Below is another way to use the code


var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext, SPHostUrl);
using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
{
if (clientContext != null)
{
FileCreationInformation newFile = new FileCreationInformation();
//here file is the selected file. In this case of type HttpPostedFileBase
newFile.ContentStream = file.InputStream;
newFile.Url = Path.GetFileName(file.FileName);
newFile.Overwrite = true;
List docs = clientContext.Web.Lists.GetByTitle("List_Name");
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
clientContext.Load(uploadFile);
clientContext.ExecuteQuery();
}
}

Note that I replaced FileStream with the input stream present in the uploaded file itself.

P.S. I have tested the above code for files upto 50 MB. It depends largely on internet speed. Once for 50MB file size it gave me time out error (which could be fixed by setting RequestTimeout property of client context)

Hope this helps.

Reference:

  1. O365 AMS

12 thoughts on “Provider Hosted App – Upload Large Files using CSOM

  1. Pingback: SharePoint 2013: Recopilatorio de enlaces interesantes (XXXIV)! - Blog de Juan Carlos González en Geeks.MS

  2. Hey Thank you for the blog!! I have a quick question. I tried uploading the file with size > 1.5MB using the second approach as mentioned by you. But the code failes when it is deployed in the map the error message says that “Could not find a part of the file”. Though the code works perfectly in the local app testing from VS 2012.

    • Please make sure that you are using the same file.

      Besides that I have added another version of the code above. In that I replaced FileStream with the input file inbuilt stream property. Please try that.

      • Input stream works with out any error. However the uploaded file will have zero bytes i.e. a blank file gets uploaded with input stream.

        BTW earlier approach works fine during debug in VS 2012. But when the app is deployed in the server it fails not sure what might be the reason.

  3. Pingback: Provider Hosted App – Copy Document across Site Collections | My SharePoint Learnings

  4. Where is the code in this article …. I cant find any code here , i’m in the same requirement .. i tried with the CSOM but im getting access denied error while reading the file from FileUpload Control , so please help me in this.

  5. Pingback: Using MIP SDK in SharePoint | My SharePoint Learnings

Leave a comment