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:
- File.SaveBinaryDirect
- 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
Pingback: SharePoint 2013: Recopilatorio de enlaces interesantes (XXXIV)! - Blog de Juan Carlos González en Geeks.MS
Wow.!! i am just new to sharepoint got to know many thing after reading here!
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.
Yeah may be some problem with the environment.
Pingback: Provider Hosted App – Copy Document across Site Collections | My SharePoint Learnings
Can we upload large files (more than 100 MB) using rest in JavaScript? And how?
Yes you can. REST supports upto 2GB. I have not tried REST approach but you can find the sample code here.
http://www.shillier.com/archive/2013/03/26/uploading-files-in-sharepoint-2013-using-csom-and-rest.aspx
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.
The code is embedded in the article itself, yet you can find it at https://gist.github.com/garima2510/b1167e611ffb495848ec#file-uploadfilelarge-cs or https://gist.github.com/garima2510/416a807b43168c6bd5d1#file-uploadfilestream-cs.
If you are getting access denied, then make sure the permissions are proper in AppManifest.xml file (if you are using app)
Pingback: Using MIP SDK in SharePoint | My SharePoint Learnings