Uploading files using Client Object Model in SharePoint 2010
There are 2 ways to upload files to SharePoint 2010 document libraries using managed client object model.
The first method uses a client library batch mechanism. It will encode the binary using BASE64 encoding, which could increase the message size by one third. There might be problems if this isn’t configured correctly. An example of this code is below:
1: ClientContext context = new ClientContext("https://spdevinwin");
2:
3: Web web = context.Web;
4:
5: FileCreationInformation newFile = new FileCreationInformation();
6: newFile.Content = System.IO.File.ReadAllBytes(@"C:\Work\Files\17580_FAST2010_S05_Administration.pptx");
7: newFile.Url = "17580_FAST2010_S05_Administration 4MB file uploaded via client OM.pptx";
8:
9: List docs = web.Lists.GetByTitle("Documents");
10: Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
11: context.Load(uploadFile);
12: context.ExecuteQuery();
13: Console.WriteLine("done");
The above code might fail throwing a (400) Bad Request error depending on the file size. The following code is used to set a higher limit to the upload size. Note: This is not the same as the max. file size upload limit option available in the web application settings.
1: SPWebService ws = SPWebService.ContentService;
2: SPClientRequestServiceSettings clientSettings = ws.ClientRequestServiceSettings;
3: clientSettings.MaxReceivedMessageSize = 10485760;
4: ws.Update();
5: Console.WriteLine(clientSettings.MaxReceivedMessageSize);
The above code sets the message batch size to 10MB so that larger files can be uploaded using managed client object model.
The second methods uses HTTP DAV and sends raw binary across the wire and does not increase the message size. It is also the preferred upload method when using managed client object model. Here’s a sample:
1: ClientContext context = new ClientContext("https://spdevinwin");
2: using (FileStream fs = new FileStream(@"C:\Work\Files\17580_FAST2010_S03_Arch.pptx", FileMode.Open))
3: {
4: Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, "/documents/17580_FAST2010_S03_Arch from client OM.pptx", fs, true);
5: }
Hope this helps! Stay tuned for most posts on managed client object model.
Comments
- Anonymous
May 09, 2010
Hi Sridhara, Really excellent article. It helped me a lot. I am using the second method(i.e. using FileStream object) to upload files. I am using multiple threads to upload files to same or different libraries in sharepoint 2010 from my win application. I am getting following errors sometimes:
- Cannot invoke HTTP DAV request. There is a pending query.
- The remote server returned an error: (409) Conflict. Can you please let me know the root cause for these and any workaround possible for these issues? Thanks in advance.
Anonymous
June 16, 2010
Hi Sridhara Thanks for this article. It help me alot @am20an if you still face the problem or anybody else is having then here is the solution which work for me ClientContext ctx = new ClientContext("http://yoursharepointURL"); Web currentWeb = ctx.Web; ctx.Load(currentWeb); ctx.ExecuteQuery(); using (FileStream fs = new FileStream(@"C:dataTestFile.pptx", FileMode.Open)) { Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, "/Sample Documents/TestFile from client.pptx", fs, true); } Console.WriteLine("Uploaded File Successfully"); and be sure the "http://yoursharepointURL/Sample Documents" is a valid path where you want to upload the file. Hope this work for you too. Thanks & Regards Reetika Tomer (MCTS - .Net Framework 2.0, Web Applications) Sr. Software Engineer Daffodil Software Ltd Gurgaon (HR) IndiaAnonymous
June 20, 2010
Hi Sridhara, thanks for example code! It works fine on the server-machine, but using a other system in the network the method "SaveBinaryDirect" throw an exception ("The underlying connection was closed: A connection that was expected to maintain their closed down the server"). My activedirectory user has full permission for the site. I think it isn't a permission problem, because all other functions for example read items or updating items works fine. Only the method SaveBinaryDirect() throw an exception. Do you know this error? I hope you can help me. Best regards! SvenAnonymous
July 08, 2010
Hey is there anyway to attach meta data to the document during upload )with either method)? or do you have to come back and do it after?Anonymous
September 12, 2010
Hi, I too am having problems uploading files using SaveBinaryDirect. I keep getting an error HTTP DAV, the same as am20an. Have you a solution for this? Kind regardsAnonymous
September 15, 2010
@Blaithin please forgive the asking of potentially stupid questions, I'm just trying to narrow down the problem scope and make sure there's actually a bug: Can you connect Windows on the machine you're using directly to the SP site's WebDAV? google.com/search Is the URL you've passed as a parameter to the client context constructor the same URL you'd use to connect to the WebDAV through Windows on that client machine?Anonymous
October 20, 2010
hi, can COM loads 2007 sharepoint sites??? im getting error. "The remote server returned an error: (500) Internal Server Error".?Anonymous
October 20, 2010
hi, can COM loads 2007 sharepoint sites??? im getting error. "The remote server returned an error: (500) Internal Server Error".?Anonymous
November 10, 2010
Hi, I have problem too (The remote server returned an error: (409) Conflict.) I try to create item with attach in a custom list in SharePoint 2010 from a simple Windows Form Im working in localmachine and i am Administrator in the server and in the SharePoint Can u helpme? Thanks //using IO= System.IO; public string NewItemAdjunto(string _nombreLista, string _url, string _titulo, string _detalles, string _pathArchivo) { try { using (ClientContext ctx = new ClientContext(_url)) { Uri url = new Uri(_url); Web site = ctx.Web; ctx.Load(site); ctx.Load(site.Lists); string itemId = "13"; List lista = ctx.Web.Lists.GetByTitle(_nombreLista); ListItemCreationInformation newInfo = new ListItemCreationInformation(); ListItem item = lista.AddItem(newInfo); // Agregamos Valores item["Title"] = _titulo; item["Descripci_x00f3_n"] = _detalles; item["Fecha"] = new DateTime(2010, 11, 10, 8, 0, 0);// Fecha en Duro item.Update(); ctx.ExecuteQuery(); using (IO.FileStream strm = new IO.FileInfo(@"C:TestAdjunto1.txt").Open(IO.FileMode.Open)) { Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, "/Lists/Contenido%201/Attachments/" + itemId + "/" + "Adjunto1.txt", strm, true); } } return "Item Creado con Adjunto"; } catch { throw; } }Anonymous
December 30, 2010
Hi All, I am getting the error -The remote server returned an error: (404) Not Found. While adding the attachment to the list Item using Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, attachmentPath, stream, true); In my case i have created an event receiver feature already running on this list, which will add an attachment to the list item and will delete the same when the item is added. I hope this will create the attachment folder for this list item, but still while adding attachments i'am getting the above file not found exception. Please anybody guide me on this . Thanks in Advance, Dhileep.Anonymous
January 10, 2011
Plz post code for list item with attachment. here only document libraryAnonymous
January 27, 2011
The comment has been removedAnonymous
February 03, 2011
I found the first method did not work for me until I added a context.Load(docs); between lines 10 and 11.Anonymous
April 14, 2011
Sven/Sridhara Did you guys found any solution for exception ("The underlying connection was closed: A connection that was expected to maintain their closed down the server"), if so can you please post it here.Anonymous
May 03, 2011
Hi I can not upload a file more than 3 mb. can u tell me how to upload large files is thr any way?? I want to use client object model no server side code I want. Thanks Bijay http://www.fewlines4biju.comAnonymous
July 13, 2011
Hi I tried to implement the second way to upload documents into SharePoint Foundation 2010 however, all the documents were saved as checked out if "Required Checked Out" option is enabled for a document library. If anyone had encountered similar problem, a little guidance would be helpful. Thanks ManiAnonymous
July 27, 2011
This is a great article. Thank You!Anonymous
August 21, 2011
When trying to run from my dev system, getting this same exception "client requestexception Cannot invoke HTTP DAV request". hope someone posts the solution quickly.Anonymous
October 02, 2011
Hello, I am getting the same exception "Cannot invoke HTTP DAV request", Did anyone resolve it?please let me knowAnonymous
October 10, 2011
ClientContext clientContext = new ClientContext(siteUrl); List CurrentList = clientContext.Web.Lists.GetByTitle(libraryName); clientContext.Load(CurrentList.RootFolder); clientContext.ExecuteQuery(); using (FileStream fileStream = new FileStream(fileName, FileMode.Open)) ClientOM.File.SaveBinaryDirect(clientContext, CurrentList.RootFolder.ServerRelativeUrl.ToString() + "/" + fileName.Split('')[1], fileStream, true); We need to Load the Document Libraries' Root Folder before we execute the query. I've changed the code accordingly and it worked fine for me, I've tested it with Uploading 40 MB file and it went well. Try It. Cheers, Satish CheeliAnonymous
October 18, 2011
Nice article, thanks. What is the size limit on WebDav solution?Anonymous
November 07, 2011
I had the following two errors: Error 1 = The remote server returned an error: (409) Conflict Error 2 = Cannot invoke HTTP DAV request. There is a pending query Dug through Google but found no solution.... finally I tried playing with the "SPC.ClientContext" path and the "fileUrl" path ... BINGO ... it got fixed. Below is before and after code: BEFORE: SPC.ClientContext clientContext = new SPC.ClientContext("http://dev:44941/ParentSite"); string fileUrl = "/CreatedDocs/MyDoc.docx"; AFTER SPC.ClientContext clientContext = new SPC.ClientContext("http://dev:44941"); string fileUrl = "/ParentSite/CreatedDocs/MyDoc.docx"; Hope this helps someone.Anonymous
November 24, 2011
Hi, Try checking or a Pending request first, like so: if (clientContext.HasPendingRequest) clientContext.ExecuteQuery(); FileInformation fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, (string)v["FileRef"]);Anonymous
January 20, 2012
SaveBinaryDirect throws 403 error if used with saml claims authentication. Bug? Any workarounds?Anonymous
January 30, 2012
Is anyone monitoring this blog? All I see are tons of questions with no responses.Anonymous
January 30, 2012
Sure why not just leave your requirements and Sridhar can develop your solution FOC!Anonymous
May 15, 2012
The comment has been removedAnonymous
June 18, 2012
Hi, I could not finr SPwebService class in Managed client object model..?? how I could get it?? Title of this blog post suggest that we can upload large files with the help of Client Object Model but code is say something diffrent isn't it? I want to use first methos might be second one work but I need First one for updating metadata with upload folder..Anonymous
January 08, 2013
The comment has been removedAnonymous
January 14, 2013
HI , Please can anyone tell me how to authenticate Rest service. I am doing the same but getting exception while doing any thing with sharepoint. I belive this is due to service is not authenticate. So please can any one explain how to do that. Regards, ManojAnonymous
March 05, 2013
hI i'm getting 401 error while using the upload with client model as it is working fine on local system. but throwing 401 .. any work arround for big size file upload using client object model.Anonymous
March 12, 2013
When using your second approach (SaveBinaryDirect) uploading to a document library works fine, unless you try to upload an exe file. Is there a limitation for some file types in SaveBinaryDirect or how can I solve this problem?Anonymous
May 29, 2013
Thanks Sridhar It resolved my problemAnonymous
June 20, 2013
I'm getting a 403 Forbidden when trying the HTTP DAV method and passing through authentication credentials. The first method works file but the file sizes are to big!!Anonymous
September 19, 2013
Thanks, the code works like a charm!Anonymous
October 24, 2013
I used second method and uploaded document successfully. But all files are Checked out. I found some code to Check in the the file. But I got Permission error. I just wondering what kind of permission is needed (I can already upload the file). Below is the code. Thanks, John public void TestUsingSharePointClient() { string sharePointServer = @"https://spo.mycompany.com"; string sharePointRoot = @"/sites/My Documents"; string sharePointFileUrl = null; string locaFilePath = @"C:PlaygroundZZZ_TestDatamy test file.txt"; using (ClientContext context = new ClientContext(sharePointServer)) { context.Credentials = new NetworkCredential("john", "password", "domain"); // NOTE1: Below three lines seems unnecessary Web currentWeb = context.Web; context.Load(currentWeb); context.ExecuteQuery(); using (FileStream fs = new FileStream(locaFilePath, FileMode.Open)) { sharePointFileUrl = sharePointRoot + "/Level One/Level Two/John Test Doc.txt"; Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, sharePointFileUrl, fs, true); } //Update metadata and check in the file Microsoft.SharePoint.Client.File file = context.Web.GetFileByServerRelativeUrl(sharePointFileUrl); //Checkout if checked in context.Load(file); context.ExecuteQuery(); // <<<<<< I got permission error. Want kind of permission do I need. if (file.CheckOutType == CheckOutType.None) { file.CheckOut(); } file.CheckIn("Batch upload", CheckinType.OverwriteCheckIn); // more code update the fields ...Anonymous
November 13, 2013
Hi John, have you checked if any mandatory metadata is not filled in? You can edit the properties directly in Sharepoint to find that mandatory metadata and then try a manual CheckIn, Regards,Anonymous
November 13, 2013
I also have the problem with the webdav pending request!!! Any help is highly appreciated!Anonymous
November 13, 2013
In my project i was just able to fix that webdav error i got about pending requests. The pending request warning is actually a mention that there is no access to an UPDATE or EXECUTEQUERY statement. Thus, this is not related to the SaveBinaryDirect function but to other function in your code. In my case i tried just doing a savebinarydirect (with the root ClientContext and with the full path including the subsitename path as parameter) and it worked perfectly. After adding the file i was getting the file back into a File-object to modify some metadata. I still used the root client context to do that, but then you need to switch back to the specific subsite client context. For me that was the key for not having the pending webdav error anymore.... Hope i could help someone with this. btw: i use Sharepoint 2013 (on premise)Anonymous
December 09, 2013
HI, Please anybody tell me how to call webservice for file increase size limit, What is the webservice do i need to call to increase the file size limit in client object model please anybody help me .Anonymous
July 14, 2014
Thanks ! Nice Topic.Anonymous
August 10, 2014
hi, i facing the error while uploading the file, all the file are saving in the same name "newFile.Url = "17580_FAST2010_S05_Administration 4MB file uploaded via client OM.pptx";"Anonymous
September 11, 2014
I want to create a write in MemoryStream and then put the same in Shared documents in Sharepoint Below is the code I am trying:- var clientContext = new ClientContext("https://server.info/"); string fileUrl = "/Shared Documents/NewDocumentFromTemplate.txt"; var ms = new MemoryStream(); using (var file = new StreamWriter(ms)) { file.WriteLine("Wrinting in file"); } Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileUrl, ms, true); Its actually creating a new file as NewDocumentFromTemplate.txt but it is empty. Its not writing anything. :( Actuallly I want to create a file on fly and then upload it in share point. Please help I am first time working with Share Point client.Anonymous
November 27, 2014
Hi, Try checking or a Pending request first, like so: if (clientContext.HasPendingRequest) clientContext.ExecuteQuery(); FileInformation fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, (string)v["FileRef"]); that's working for me... thanksAnonymous
January 07, 2015
The second method doesn't work when you have required columns in the document library or list.... The first method works as long as you run a powershell command on the Web front end and do iis reset on the all the servers in the farmAnonymous
January 15, 2015
Can someone help... I would prefer to build out this solution with javascript. I am using a SharePoint 2010 Enterprise environment. I have successfully translated all the code from C# to javascript except the coup-de-gras: SPFileCollection.Add(). I consistently receive two errors based on differences in my code. Please take a look and provide suggestions if you can: #################################
CODE 1 START
################################# var item = null; var clientContext = new SP.ClientContext.get_current(); var oList = clientContext.get_web().get_lists().getByTitle(libraryName); clientContext.load(oList); var itemCreateInfo = new SP.ListItemCreationInformation(); itemCreateInfo.set_underlyingObjectType(SP.FileSystemObjectType.file); itemCreateInfo.set_leafName(fileName); item = oList.addItem(itemCreateInfo); item.set_item("ContentTypeId", "0x0101"); item.set_item('Title', fileName); item.update(); clientContext.load(item); clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed)); #################################
CODE 1 END
################################# The above code produces the following error: Request failed. To add an item to a document library, use SPFileCollection.Add() #################################
CODE 2 START
################################# var item = null; var clientContext = new SP.ClientContext.get_current(); _oList = clientContext.get_web().get_lists().getByTitle(libraryName); clientContext.load(_oList , "RootFolder"); var rootFolder = _oList.get_rootFolder(); var files = rootFolder.get_files(); var fileStr = "Hello World"; var bytes = []; for (var i = 0; i < fileStr.length; ++i) { bytes.push(fileStr.charCodeAt(i)); } this.newFile = files.add(fileName,bytes,true); clientContext.executeQueryAsync(Function.createDelegate(this, this.OnQuerySucceeded), Function.createDelegate(this, this.onQueryFailed)); #################################
CODE 2 END
################################# The above code produces the following error: TypeError: Object doesn’t support property or method 'add'
Anonymous
January 16, 2015
@Jmune: When you use # CODE 1 START one did you update clientSettings.MaxReceivedMessageSize using powershell? Once you update that setting on the server you need to perform iisreset on all the servers in the farm. Here is the complete script that you need to run and do iisreset to be able to upload for the files upto 50MB $ws = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $ws.ClientRequestServiceSettings.MaxReceivedMessageSize = 52428800 $ws.Update()Anonymous
January 19, 2015
@SharePoint 6996: I did not update with PowerShell. The files I need to add are only a few Kilobytes. I found a solution with .addTemplateFile. What really helped was the following code that identifies most (if not all) functions for JS objects: function getMethods(txt,obj) { var res = []; var listInfo; var dispLimit = 50; var currCount = 0; for(var m in obj) { //if(typeof obj[m] == "function") { res.push(m); listInfo += m + 'n'; currCount += 1; //} if(currCount > dispLimit) { alert(txt + 'nn' + listInfo); currCount = 0; listInfo = ""; } } alert(txt + 'nn' + listInfo); return listInfo; } After the fact, I found a code snippet on this site: jeremybranham.wordpress.com/.../sharepoint. It has most of the solution I am looking for. Now I just need to convince the system to add content to the files.