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/.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s