Skip to content

CSOM Update File and Create New Version in Document Library

October 11, 2013

In one of my recent task, I need to upload a file to a document library using CSOM C#.  The requirement also states that if the same file already exists at the target location, the file should be updated and a new file version should be created.

I started by using Microsoft.SharePoint.Client.File.CopyTo method:

sourceFile.CopyTo(desinationUrl, false)

It will throw exception when a file with same name already exists. Changing the overwrite flag to true will overwrite the existing file, but the existing version history is lost,  and a new 1.0 version is created. After searching Internet and doing some test, it finally worked out the code that meets the requirement by copying the file stream to memory stream first and then updating the existing file using File.SaveBinaryDirect(…) method.

The complete working code is shown as follows:

        public void CopySharePointDocument(string siteUrl, string srcUrl, string desinationUrl)
        {
            var relativeSrcUrl = srcUrl.Substring(srcUrl.IndexOf('/', 8));
            var relativeDestinationUrl = desinationUrl.Substring(desinationUrl.IndexOf('/', 8));
            File existFile = GetFile(siteUrl, relativeDestinationUrl);

            using (ClientContext ctx = new ClientContext(siteUrl))
            {
                ctx.Credentials = new NetworkCredential(_username, _password, _domain);
                var site = ctx.Web;
                var sourceFile = site.GetFileByServerRelativeUrl(relativeSrcUrl);
                ctx.Load(sourceFile);
                ctx.ExecuteQuery();
                if (existFile!=null)
                {
                    UpdateFile(ctx, relativeSrcUrl, relativeDestinationUrl);
                }
                else
                {
                    sourceFile.CopyTo(desinationUrl, false);
                }
                ctx.ExecuteQuery();
            }
        }

        static private void CopyStream(Stream source, Stream destination)
        {
            byte[] buffer = new byte[32768];
            int bytesRead;
            do
            {
                bytesRead = source.Read(buffer, 0, buffer.Length);
                destination.Write(buffer, 0, bytesRead);
            } while (bytesRead != 0);
        }

        private void UpdateFile(ClientContext ctx, string relativeSrcUrl, string relativeDestinationUrl)
        {

            FileInformation fileInformation = File.OpenBinaryDirect(ctx, relativeSrcUrl);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                CopyStream(fileInformation.Stream, memoryStream);
                memoryStream.Seek(0, SeekOrigin.Begin);
                File.SaveBinaryDirect(ctx, relativeDestinationUrl, memoryStream, true);
            }
        }

        public File GetFile(string siteUrl, string relativeUrl)
        {
            using (ClientContext ctx = new ClientContext(siteUrl))
            {
                ctx.Credentials = new NetworkCredential(_username, _password, _domain);
                var site = ctx.Web;
                var file = site.GetFileByServerRelativeUrl(relativeUrl);
                try
                {
                    ctx.Load(file);
                    ctx.ExecuteQuery(); // this will throw exception if the file does not exist
                    return file;
                }
                catch (ServerException ex)
                {
                    if (ex.Message == "File Not Found.")
                    {
                        return null;
                    }
                    throw;
                }
            }
        }

From → SharePoint 2010

3 Comments
  1. SaveBinaryDirect method throws 500 internal server error. Any idea why would I get that error?
    I am just using your code in a console application.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: