Saving and Updating Documents with the SharePoint Client Object Model

Working programmatically with SharePoint tends to mean 1 of 2 things – either using the SharePoint API or using SharePoint’s web services.

The application I work on uses SharePoint as a DMS – something that Microsoft has been pushing more and more recently.

My app is client-side, so that rules out the SharePoint API. To use the SharePoint API you need to install some flavour of SharePoint on your dev box and your finished solution must live on the SharePoint server.

We could have used SharePoint web services but they’re not the easiest to work with and our app needs to work with many different sites at the same time. Instead we chose to use a higher level library that required less SharePoint knowledge. We turned to HubKey’s SharePoint Library – which uses FrontPageRPC behind the scenes.

All was fine until we upgraded from WSS 3.0 to WSS 4.0 (or SharePoint Foundation Services 2010 to use its full handle). Then the HubKey stuff no-worky-worky...

Instead Microsoft has come up with the SharePoint Client Object Model which, similar to the HubKey library, allows client applications to work with SharePoint sites without needing to use web services.

The SharePoint COM requires you to reference Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.Runtime (which can be found on a SharePoint server – but does not require you to install SharePoint on your dev machine.

The articles at MSDN show how the COM proxies your requests as XML to the SharePoint installation and receives results as JSON.

Here’s an example of how you might create a StoreDocument method – that will update a previously stored document as necessary. Note that CAML remains the SharePoint way for querying lists.

public void StoreDocument2(string webUrl, string localFile)
{
    ClientContext clientContext = new ClientContext(webUrl);
    Web web = clientContext.Web;
    List documentLibrary = web.Lists.GetByTitle("Documents");

    CamlQuery camlQuery = new CamlQuery();
    camlQuery.ViewXml = string.Format(
                                    @"<View>
                                    <Query>
                                        <Where>
                                        <Eq>
                                            <FieldRef Name='FileLeafRef'/>
                                            <Value Type='Text'>{0}</Value>
                                        </Eq>
                                        </Where>
                                        <RowLimit>1</RowLimit>
                                    </Query>
                                    </View>", System.IO.Path.GetFileName(localFile));

    ListItemCollection listItems = documentLibrary.GetItems(camlQuery);

    clientContext.Load(documentLibrary);
    clientContext.Load(listItems);
    clientContext.ExecuteQuery();

    FileCreationInformation newFile = new FileCreationInformation();
    newFile.Content = System.IO.File.ReadAllBytes(localFile);
    newFile.Url = System.IO.Path.GetFileName(localFile);

    // if file exists update it
    if (listItems.Count > 0)
    {
        newFile.Overwrite = true;
    }

    Microsoft.SharePoint.Client.File uploadFile = documentLibrary.RootFolder.Files.Add(newFile);

    clientContext.Load(uploadFile);
    clientContext.ExecuteQuery();
}

The MSDN documentation is here: http://msdn.microsoft.com/en-us/library/ee537247.aspx

And Channel 9 resources can be found here: http://channel9.msdn.com/Learn/Courses/SharePoint2010Developer/ClientObjectModel

Comments