In my previous post, I had explained how to upload large files up to 10 GB to SharePoint Online. This is as per the new revised upload limit. The upload operation, as we know, is actually incomplete without download. I mistakenly, assumed that the previous code for file download will work for the latest larger files as well. But, just like I had to rewrite the upload code to accommodate this new limit, file download also needed a complete makeover. I initially tried the following ways with no success.
Tag: RPC
Remove/Delete an existing SharePoint File C# RPC
private void RemoveDocument(string documentName) { string requestUrl = this.ctx.Url + "/_vti_bin/_vti_aut/author.dll"; string method = GetEncodedString("remove documents:15.0.0.4420"); string serviceName = GetEncodedString(ctx.Web.ServerRelativeUrl); string url_List = GetEncodedString(String.Concat("[", documentName, "]")); rpcCallString = "method={0}&service_name={1}&url_list={2}\n"; rpcCallString = String.Format(rpcCallString, method, serviceName, url_List).Replace("_", "%5f"); HttpWebRequest wReq = WebRequest.Create(requestUrl) as HttpWebRequest; wReq.Method = "POST"; wReq.Headers["Content"] = "application/x-vermeer-urlencoded"; wReq.Headers["X-Vermeer-Content-Type"] = "application/x-vermeer-urlencoded"; wReq.UserAgent = "FrontPage"; wReq.UseDefaultCredentials = false; Uri targetSite = new Uri(this.ctx.Web.Url); SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)this.ctx.Credentials; string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite); wReq.CookieContainer = new CookieContainer(); wReq.CookieContainer.Add( new Cookie("FedAuth", authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()), String.Empty, targetSite.Authority)); using (IO.Stream requestStream = wReq.GetRequestStream()) { byte[] rpcHeader = Encoding.UTF8.GetBytes(rpcCallString); requestStream.Write(rpcHeader, 0, rpcHeader.Length); requestStream.Close(); GetResponse(wReq); } } private string GetResponse(HttpWebRequest webRequest) { string responseString = String.Empty; using (WebResponse webResponse = webRequest.GetResponse()) { using (StreamReader reader = new StreamReader(webResponse.GetResponseStream())) { responseString = reader.ReadToEnd(); byte[] fileBuffer = Encoding.UTF8.GetBytes(responseString); } } if ((responseString.IndexOf("message=successfully") < 0) && (responseString.IndexOf("msg=Save Conflict") < 0)) { throw new Exception(responseString); } return responseString; }
Now, let’s evaluate this.
- Here we are using method “remove documents” and, “15.0.0.4420” is server extension version.
- Service name is server relative URL of your site.
- documentName is the name of the document to be deleted. For ex. if the doc ToBeDeleted.aspx resides in the root folder of the site then, documentName will be ToBeDeleted.aspx.
- For authentication, we’re using the CookieContainer of HTTPWebRequest.
Here is the example of how will you call this upload method.
RemoveDocument("ToBeDeleted.aspx");
One utility method has been used here for encoding of string. Here it is for your reference.
public string GetEncodedString(string sourceString) { if (!String.IsNullOrEmpty(sourceString)) { return HttpUtility.UrlEncode(sourceString).Replace(".", "%2e").Replace("_", "%5f"); } else { return sourceString; } }
Rename/Move an Existing SharePoint File using RPC C#
public void RenamePage(string oldUrl, string newUrl) { string requestUrl = this.ctx.Url + "/_vti_bin/_vti_aut/author.dll"; string method = GetEncodedString("move document:15.0.0.4420"); string serviceName = GetEncodedString(this.ctx.Web.ServerRelativeUrl); oldUrl = GetEncodedString(oldUrl); newUrl = GetEncodedString(newUrl); string urlList = GetEncodedString("[]"); rpcCallString = "method={0}&service_name={1}&oldUrl={2}&newUrl={3}&url_list={4}&rename_option=findbacklinks&put_option=edit\n"; rpcCallString = String.Format(rpcCallString, method, serviceName, oldUrl, newUrl, urlList).Replace("_", "%5f"); HttpWebRequest wReq = WebRequest.Create(requestUrl) as HttpWebRequest; wReq.Method = "POST"; wReq.Headers["Content"] = "application/x-vermeer-rpc"; wReq.Headers["X-Vermeer-Content-Type"] = "application/x-vermeer-rpc"; wReq.UserAgent = "FrontPage"; wReq.UseDefaultCredentials = false; Uri targetSite = new Uri(this.ctx.Web.Url); SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)this.ctx.Credentials; string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite); wReq.CookieContainer = new CookieContainer(); wReq.CookieContainer.Add( new Cookie("FedAuth", authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()), String.Empty, targetSite.Authority)); wReq.BeginGetRequestStream(new AsyncCallback(gotRequestStream), wReq); } private void gotRequestStream(IAsyncResult asynchronousResult) { HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState; Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult); List<byte> uploadData = new List<byte>(); uploadData.AddRange(Encoding.UTF8.GetBytes(rpcCallString)); byte[] fileData = uploadData.ToArray(); requestStream.Write(fileData, 0, fileData.Length); requestStream.Close(); webRequest.BeginGetResponse(new AsyncCallback(gotResponse), webRequest); } private void gotResponse(IAsyncResult asynchronousResult) { HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult); Stream responseStream = webResponse.GetResponseStream(); StreamReader reader = new StreamReader(webResponse.GetResponseStream()); string responseString = String.Empty; responseString = reader.ReadToEnd(); byte[] fileBuffer = Encoding.UTF8.GetBytes(responseString); responseStream.Close(); reader.Close(); webResponse.Close(); if (responseString.IndexOf("\n message=successfully" ) < 0) { throw new Exception(responseString); } }
Now, let’s evaluate this.
- Here we are using method “move document” and, “15.0.0.4420” is server extension version.
- Service name is server relative URL of your site.
- oldUrl is the current url of the page and newUrl is the new url to be set.
- For authentication, we’re using the CookieContainer of HTTPWebRequest.
Here is the example of how will you call this upload method.
RenamePage("default.aspx", "defaultNew.aspx");
Here a utility method, GetEncodedString has been used here for encoding of string. Here it is for your reference.
public string GetEncodedString(string sourceString) { if (!String.IsNullOrEmpty(sourceString)) { return HttpUtility.UrlEncode(sourceString).Replace(".", "%2e").Replace("_", "%5f"); } else { return sourceString; } }
Check out here to get some additional info about move document, http://msdn.microsoft.com/en-us/library/ms440627%28v=office.14%29.aspx.
Upload Large Files to the SharePoint DocumentLibrary using RPC from a Desktop Application C#
In one of my previous post, https://realmpksharepoint.wordpress.com/2014/01/19/upload-a-file-to-sharepoint-using-client-object-model/ , I had shown how we can upload documents to SharePoint using CSOM. Though, the client object model was working perfectly for smaller documents, it started throwing time-out errors when I tried to upload a file of size around 40MB (previously, I was uploading documents < 2MB).
So to upload large documents I am going to use RPC. RPC is an interprocess communication technique that allows client and server software to communicate. For more details of RPC you can visit WikiPedia and TechNet articles.
public void UploadFile(string currentWebUrl, string serviceName, string filePath, FileStream stream, string userDomainName) { newFileData = null; newFileData = new byte[stream.Length]; stream.Read(newFileData, 0, Convert.ToInt32(stream.Length)); string requestUrl = currentWebUrl + "/_vti_bin/_vti_aut/author.dll"; string method = GetEncodedString("put document:15.0.0.4420"); serviceName = GetEncodedString("/" + serviceName); string putOption = "overwrite"; string metaInfo = "[vti_modifiedby;SW|" + userDomainName + ";vti_author;SW|" + userDomainName + "]]"; string comments = GetEncodedString("File uploaded using RPC call"); string docDetails = String.Format("[document_name={0};meta_info={1}", filePath, metaInfo); docDetails = GetEncodedString(docDetails); rpcCallString = "method={0}&service_name={1}&document={2}&put_option={3}&comment={4}&keep_checked_out=false\n"; rpcCallString = String.Format(rpcCallString, method, serviceName, docDetails, putOption, comments).Replace("_", "%5f"); HttpWebRequest wReq = WebRequest.Create(requestUrl) as HttpWebRequest; wReq.Method = "POST"; wReq.Headers["Content"] = "application/x-vermeer-urlencoded"; wReq.Headers["X-Vermeer-Content-Type"] = "application/x-vermeer-urlencoded"; wReq.UserAgent = "FrontPage"; wReq.UseDefaultCredentials = false; Uri targetSite = new Uri(this.ctx.Web.Url); //Get the credential for authentication SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)this.ctx.Credentials; //Retrieve the authentication cookie with the help of credentials string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite); wReq.CookieContainer = new CookieContainer(); wReq.CookieContainer.Add( new Cookie("FedAuth", authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()), String.Empty, targetSite.Authority)); wReq.BeginGetRequestStream(new AsyncCallback(gotRequestStream), wReq); } private void gotRequestStream(IAsyncResult asynchronousResult) { HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState; Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult); List<byte> uploadData = new List<byte>(); uploadData.AddRange(Encoding.UTF8.GetBytes(rpcCallString)); uploadData.AddRange(newFileData); byte[] fileData = uploadData.ToArray(); requestStream.Write(fileData, 0, fileData.Length); requestStream.Close(); webRequest.BeginGetResponse(new AsyncCallback(gotResponse), webRequest); } private void gotResponse(IAsyncResult asynchronousResult) { HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult); Stream responseStream = webResponse.GetResponseStream(); StreamReader reader = new StreamReader(webResponse.GetResponseStream()); string responseString = String.Empty; responseString = reader.ReadToEnd(); byte[] fileBuffer = Encoding.UTF8.GetBytes(responseString); responseStream.Close(); reader.Close(); webResponse.Close(); if (responseString.IndexOf("\n message=successfully" ) < 0) { //Indicates that the SharePoint has returned an error message. The document might have got uploaded also so one should better check the message first. throw new Exception(responseString); } }
Now, let’s evaluate this.
- Here we are using the method, “put document” and, “15.0.0.4420” is server extension version.
- Service name is server relative URL of your site.
- In document parameter we are providing to fields “document_name” and “meta_info”. Document name is the path at which we want to upload the file including the file name and meta info sets the metadata of the document to be uploaded. MetaInfo is a system site-column where SharePoint stores custom values related to that particular ListItem.
- Next parameter is put_option where you can provide “overwrite” if you want to overwrite existing file with same name else you can provide “edit”.
- Next two parameters comment and keep_checked_out are very straight forward.
- For authentication, we’re using the CookieContainer of HTTPWebRequest.
In case of RPC calls it is confusing how to pass parameters, mostly in case of file paths. So here is the example of how will you call this upload method.
UploadFile("http://myserver/sites/teamsite/", "sites/teamsite", "Shared Documents/document1.docx", fileStream, "Piyush Singh");
One utility method has been used here for encoding of string. Here it is for the reference.
public string GetEncodedString(string sourceString) { if (!String.IsNullOrEmpty(sourceString)) { return HttpUtility.UrlEncode(sourceString).Replace(".", "%2e").Replace("_", "%5f"); } else { return sourceString; } }
You can get more info about put document here, http://msdn.microsoft.com/en-us/library/ms479623.aspx.
It has been said that in this way we can upload document up to 2GB to the site. Well, I have tested it for the documents of size little over 100MB and it’s working fine.
Also, you can visit the following post to upload files up to 10GB to SharePoint Online,
https://realmpksharepoint.wordpress.com/2016/07/22/upload-large-files-to-sharepoint-online/.