Tuesday, January 8, 2013

File not found exception in Office 2010 addin / ClientContext Code not executing

When we add any reference dlls(say in the example Microsoft.SharePoint.Client dll)  in Office 2010 addin and package it using Click once and install it in client machine it gives an


System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.SharePoint.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.

File name: 'Microsoft.SharePoint.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'

   at WordAddIn1.Form1.UploadDocument(Byte[] docbytes)

   at WordAddIn1.Form1.button1_Click(Object sender, EventArgs e)



Assembly manager loaded from:  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll

Running under executable  C:\PROGRA~1\MICROS~2\Office14\WINWORD.EXE

Fix:


Add the reference dlls in the root of the project like below and publish again. This took me a day to figure out :(.

There were no good article to debug and fix this issue in msdn forums so thought this might be useful to someone

Upload a word document from Office 2010 plugin to SharePoint Doc library

When we create a Office 2010 addin  say for word and try to access SharePoint resources from it we know pretty much better option is 'Client Object model'.

1. Create a new Word 2010 addin and a button called 'Save'
2. Include a win form and add a button called "Upload doc"
3. Call this form on click of Save button.

4 Below code is to upload a current open word document in Office 2010 to a SharePoint site without saving locally on click of Upload Doc button.



 public void UploadDocument(byte[] docbytes)
        {

            ClientContext clientContext = new ClientContext("http://sharepointsiteurl/");

            List documentsList = clientContext.Web.Lists.GetByTitle("Events");

            var fileCreationInformation = new FileCreationInformation();

            fileCreationInformation.Content = docbytes;

            fileCreationInformation.Overwrite = true;

            fileCreationInformation.Url = "http://sharepointdoclibrarylocation/la.doc";
            Microsoft.SharePoint.Client.File uploadFile = documentsList.RootFolder.Files.Add(fileCreationInformation);
            uploadFile.ListItemAllFields.Update();
            clientContext.ExecuteQuery();
}

and on button click below code grabs the current document content as byte array and calls the above function to upload it to SharePoint

 private void button1_Click(object sender, EventArgs e)
        {

            Microsoft.Office.Interop.Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument;

            doc.ActiveWindow.Selection.WholeStory();
            doc.ActiveWindow.Selection.Copy();

            IDataObject data = Clipboard.GetDataObject();

            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data.GetData(DataFormats.Html).ToString());


            MessageBox.Show("Before Upload");
            try
            {
                UploadDocument(bytes);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

            }
            MessageBox.Show("Uploaded to SharePoint Successfully");

        }

The difference from other solutions  is here we dont save the document anywhere locally instead directly grabbing the content as byte array and uploading it to SharePoint doc library which will improve the performance drastically.