Remove/Delete an existing SharePoint File C# RPC

This one deals with the removal of a document from a SharePoint site. Though this can also be achieved using CSOM but there’s one situation where the CSOM won’t be of any help, i.e., deleting a file from the root folder of a Web(SiteCollection/SubSite). Since, the root files do not belong to any List, these files cannot be handled using standard CSOM logic. For this, I am going to rely on the RPC call to the author.dll. In my previous two posts, https://realmpksharepoint.wordpress.com/2014/04/29/upload-large-files-to-the-sharepoint-documentlibrary-using-rpc-from-a-desktop-application-c/https://realmpksharepoint.wordpress.com/2014/05/09/renamemove-an-existing-sharepoint-file-using-rpc-c/ , I have demonstrated how a document (residing in the root or anywhere else) can be uploaded, moved, or renamed using 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#

In this post, I am going to demonstrate how to rename an existing file using RPC. The code is along the same line as this one, https://realmpksharepoint.wordpress.com/2014/04/29/upload-large-files-to-the-sharepoint-documentlibrary-using-rpc-from-a-desktop-application-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/.