Add Digital Signature to Documents in a Document Library using C#

I had a requirement that involved adding a digital signature to word documents uploaded on a document library when the document is approved. This article discusses step by step how to add digital signatures to word documents.

I solve this problem by using the following approach.

Step 1
Catch the update events (by writing ItemUpdated event handlers) (for more info about event handlers implementation see the previous post).


Step 2
Make a copy of your file that is approved in the document library to a temporary folder on the server.


Step 3
Add the digital signature to your own copied file on the server.


Step 4
Write the file again to your document library then remove the temporary copy on the server.


Step 5
If the file is not signed the approval status of the document will be converted into rejected.

I have used the following code to implement this entire process.

The Strings Class is a class that contains all strings used in my code. Listing 1 shows the Strings class and its members.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace DGEventReciever

{

    public class Strings

    {

        // The general keys .

 

    #region

        public const string TemporaryFolderKey = @"C:\TempFolder";

        public const string ApprovalColumnKey = "Approval Status";

    #endregion

 

    //Other Strings.

 

    #region

        public const string InDraftStatus = "0";

        public const string DateFormat = "yyyyyMMddhhmmss";

        public const string IDColumn = "ID";

        public const string NameColumn = "Name";

        public const string DocxExtension = ".docx";

        public const string DocExtension = ".doc";

    #endregion

    }
}


The Main Class that handles the events is listed in Listing 2. I have used OfficeInterop COM library. Before you use this code, you must add reference to Microsoft.Office.Interop.Word.Dll and other required assemblies.

 


using System.Web;

using Microsoft.SharePoint;

using System.IO;

using Microsoft.Office.Core;

 

namespace DGEventReciever

{

    public class DGEventHandler:SPItemEventReceiver

    {

        //All the Public Used Variables.

        #region

            public string TemporaryFolder = string.Empty;

            public string ApprovalColumnName = string.Empty;

        #endregion

 

        public override void ItemUpdated(SPItemEventProperties properties)

        {

            EventHandlerConstructor();

            if (properties.ListItem[ApprovalColumnName].ToString() == Strings.InDraftStatus)

            {

                DownloadItem(properties);

            }

        }

 

        private void EventHandlerConstructor()

        {

            TemporaryFolder = Strings.TemporaryFolderKey;

            ApprovalColumnName = Strings.ApprovalColumnKey;

        }

 

 

        private void DownloadItem(SPItemEventProperties properties)

        {

            SPFile File = properties.ListItem.File;

            string FileTempName = DateTime.Now.ToString(Strings.DateFormat) +

            properties.ListItem[Strings.IDColumn].ToString() +

            properties.ListItem[Strings.NameColumn].ToString();

 

            if (File.Name.ToLower().EndsWith(Strings.DocxExtension) ||

            File.Name.ToLower().EndsWith(Strings.DocExtension))

            {

                byte[] Filebytes = File.OpenBinary(SPOpenBinaryOptions.None);

                DirectoryInfo TempDirectory = new DirectoryInfo(TemporaryFolder);

                if (!TempDirectory.Exists)

                {

                    TempDirectory.Create();

                }

                FileStream TempFileOnDisk = new FileStream(TemporaryFolder + FileTempName,

                FileMode.CreateNew);

 

                BinaryWriter bWriter = new BinaryWriter(TempFileOnDisk);

                foreach (byte b in Filebytes)

                {

                    bWriter.Write(b);

                }

                bWriter.Flush();

                bWriter.Close();

                TempFileOnDisk.Close();

 

                bool SignatureAdded = AddDigitalSignature(FileTempName, properties);

 

                if (SignatureAdded)

                {

                    properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;

                    WriteFileAgain(properties, FileTempName);

                    properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = false;

                }

            }

        }

 

        private bool AddDigitalSignature(string FileTempName, SPItemEventProperties properties)

        {

            object TempFilePath = TemporaryFolder + FileTempName;

            object Visible = false;

            object readonlyfile = false;

 

            try

            {

                object missing = System.Reflection.Missing.Value;

                Microsoft.Office.Interop.Word.ApplicationClass wordapp = new

                Microsoft.Office.Interop.Word.ApplicationClass();

                Microsoft.Office.Interop.Word.Document wordDocument = wordapp.Documents.Open(ref

                TempFilePath, ref missing,

                ref readonlyfile, ref missing, ref missing,

                ref missing, ref missing, ref missing,

                ref missing, ref missing, ref missing,

                ref Visible, ref missing, ref missing,

                ref missing, ref missing);

                SignatureSet signatureSet = wordDocument.Signatures;

                Signature objSignature = signatureSet.Add();

                if (objSignature == null)

                {

                    DocumentNotSigned(properties);

                    return false;

                }

                else

                {

                    signatureSet.Commit();

                    object saveChanges = true;

                    wordDocument.Close(ref saveChanges, ref missing, ref missing);

                    wordapp.Quit(ref missing, ref missing, ref missing);

                    return true;

                }

            }

            catch

            {

                return false;

            }

        }

 

        private void WriteFileAgain(SPItemEventProperties properties, string TemporaryFile)

        {

            SPFile currentFile = properties.ListItem.File;

            string TempFilePath = TemporaryFolder+ TemporaryFile;

            FileStream st = new FileStream(TempFilePath, FileMode.Open);

            properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;

            currentFile.CheckOut();

            currentFile.SaveBinary(st);

            this.DisableEventFiring();

            currentFile.CheckIn(string.Empty);

            currentFile.Publish(string.Empty);

            currentFile.Approve(string.Empty);

            st.Close();

            properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = false;

            this.EnableEventFiring();

            FileInfo deletedfile = new FileInfo(TemporaryFolder + TemporaryFile);

            deletedfile.Delete();

        }

 

        private void DocumentNotSigned(SPItemEventProperties properties)

        {

 

            properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;

            SPFile currentFile = properties.ListItem.File;

            if (currentFile.CheckOutStatus == SPFile.SPCheckOutStatus.None)

            {

                currentFile.CheckOut();

            }

            this.DisableEventFiring();

            currentFile.CheckIn(string.Empty);

            currentFile.Publish(string.Empty);

            currentFile.Deny(string.Empty);

            properties.ListItem.ParentList.ParentWeb.AllowUnsafeUpdates = false;

            this.EnableEventFiring();

        }

 

    }

}






Similar Articles