Monday, May 31, 2010

Making your SharePoint 2010 applications ECM aware (Part two – Document Sets)

This is part two of a multipart series of how to take advantage of the new ECM features in SharePoint 2010. Part one of this series talked about how you enable your applications to use the SharePoint Content Organizer feature. In this post I will discuss how to do the same with the new Document Set feature in SharePoint .

Document sets are basically SharePoint folders on steroids. The original concept was to enhance team collaboration on a set of documents without having to set up an additional SharePoint site. You could also look at Document Sets as mini SharePoint document libraries. They allow you to set permissions, assign workflows, share common properties and send an email link.  However, the real power of Document Sets is contained in their ability to define a repeatable process. A custom Document Set content type can be defined and reused across a site. In addition to assigning site columns to a document set content type, you can set common shareable properties that will be given to each new document that is added to the document set. This helps group common documents by common metadata, making it easy to search and retrieve these documents. Another, great feature is the ability to define what content types are allowed to be added to the document set. This gives administrators the ability to control the metadata assigned to documents within the set. Finally, the most important feature is the ability to assign default documents to be added automatically to the document set when it is created.

Document sets are a great way to increase productivity. For example, if a loan processing company receives a home loan application, then it can be scanned into a new  custom document set which will automatically have other required documents added. For instance, a property appraisal form or a house inspection report. Also, the document set itself has required metadata that needs to be entered before any documents are added. Document sets gives businesses the ability to put a process around content, ergo “content management”.

So, lets say you have a document scanning application and you want your application to create new types document sets dynamically. How can the application emulate being able to set up a new document set like the SharePoint UI? The following code shows how to use the server side object model to set up a new document set including adding shared properties, allowable content types, and default documents. The key is the DocumentSetTemplate class which contains all the properties needed.

 

public static void CreateDocumentSetContentType(string destinationUrl,
            string documentSetTypeName, string defaultDocumentPath)
{

            using (SPSite site = new SPSite(destinationUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    //create the new document set contenttype
                    SPContentType newDocumentSetContentType = web.ContentTypes.Add
                        (new SPContentType(web.ContentTypes["Document Set"],
                            web.ContentTypes,
                            documentSetTypeName));

                    //get a DocumentSetTemplate for the new document set
                    DocumentSetTemplate newDocumentSetTemplate =
                        DocumentSetTemplate.GetDocumentSetTemplate
                        (newDocumentSetContentType);

                    //add allowable content types
                    newDocumentSetTemplate.AllowedContentTypes.Add
                        (web.ContentTypes["Document"].Id);

                    newDocumentSetTemplate.AllowedContentTypes.Add
                        (web.ContentTypes["Picture"].Id);

                    //get the default document's binary
                    FileInfo fi = new FileInfo(defaultDocumentPath);
                    byte[] defaultDocumentBytes = new byte[fi.Length];
                    FileStream fs = fi.OpenRead();
                    fs.Read(defaultDocumentBytes, 0, (int)fi.Length);
                    //add the default document
                    newDocumentSetTemplate.DefaultDocuments.Add("defaultDocument",
                        web.ContentTypes["Document"].Id, defaultDocumentBytes);

                    //add a shareable property
                    newDocumentSetTemplate.SharedFields.Add
                        (newDocumentSetContentType.Fields["Description"]);

                    //make sure to add the document set name to the default documents
                    newDocumentSetTemplate.DefaultDocuments.AddSetName = true;

                    newDocumentSetTemplate.Update(true);
                    newDocumentSetContentType.Update();
                    web.Update();
                }
            }
}

After running this code you can verify that it works by going to “Site Settings—>Site Content Types” . Find your new content type and select it.  Then you can view your settings by clicking on “Document Set Settings”. Now you can use this new document set content type to create new project folders in your document libraries.

While I was testing this code I was curious as to where the actual default documents are stored in SharePoint. They must be made available to all content types inheriting from it. At first I thought they might be stored in a site level hidden list. However they are actually stored within the SPWeb’s folder collection under “_cts”. So if you want to see the documents programatically you use the this as example to follow:

SPWeb.Folders["_cts"].SubFolders["document set name"]

Another thing your application may want to determine is if a particular file is part of a document set. The code below will take a url to a SharePoint file and return whether it is part of a document set.

       public static bool IsPartOfDocumentSet(string url)
       {

           DocumentSet ds = null;

           using (SPSite site = new SPSite(url))
           {
               using (SPWeb web = site.OpenWeb())
               {
                   object value = web.GetFileOrFolderObject(url);

                   if(typeof(SPFile).IsAssignableFrom(value.GetType()))
                   {
                       SPFile file = value as SPFile;
                       ds = DocumentSet.GetDocumentSet(file.ParentFolder);
                   }
                   else
                   {
                       if(typeof(SPFolder).IsAssignableFrom(value.GetType()))
                       {
                           SPFolder folder = value as SPFolder;
                           ds = DocumentSet.GetDocumentSet(folder);
                       }
                       else
                           return false;
                   }

                   if (ds != null)
                       return ds.ContentTypeTemplate.AllowedContentTypes.Count > 0? true : false;
                   else
                       return false;

               }
           }
         }

 

This code uses the static GetDocumentSet method of the DocumentSet class. All the code above makes use of the Microsoft.Office.DocumentManagement assembly located in the 14 hive ISAPI folder. Once you have a reference to the DocumentSet object you can interrogate it’s properties to work with it in your application. If you need to access the files in the document set you can access the Folder property of the document set which contains the Files collection.

The biggest problem with SharePoint document sets is the lack of any remote access to them. There are no client object model methods or web services to access them. It is up to the developer to create a custom web service to manipulate them remotely from the application.  You can create a document set content type through the client object model:

Creating document sets remotely

Unfortunately you cannot add the default documents and other features described above. It might be possible by manipulating the Schema property of the client object model content type by adding the xml declarations for the allowable content types and other information. Further research needs to be done on that. If I am able to do this, then I will be sure to post it here.

Document sets are a great new feature in SP2010 and can add a lot to your content management application. Unfortunately, Microsoft needs to give us access to them remotely.

1 comment:

Anonymous said...

Steve, the question I have is can I create a documentset via an sandboxed solution? We've limited by our organization on deploying farm solutions.

Post a Comment