SharePoint 4 Developers

Additional reference guide in .NET / SharePoint Development

Creating Document Sets Programmatically

In this post I will show how to create document sets programmatically, by exploring the assembly Microsoft.Office.DocumentManagement.dll, available at the directory \14\ISAPI.

Hi folks,

I have been requested to create lots of document sets in replacement of folders recently. It is easy to create document sets manually, but when you need to create lots of them, the best solution is to do it programmatically.

Document sets are more than simple folders. They hold metadata, which is changing the way users are working and they are taking advantage of it.

As a quick note, in this post I will show how to create document sets programmatically, by exploring the assembly Microsoft.Office.DocumentManagement.dll, available at the directory \14\ISAPI\.

The Solution

Basically this solution shows how to create a document set and add it to a Document Library.

Note: 2 content types were created manually for demonstration purposes: Word Template and Excel Spreadsheet Template.

Check this out:

Code Snippet
  1. static void Main(string[] args)
  2. {
  3.     var url = ConfigurationManager.AppSettings["Url"].ToString();
  4.     var sub = ConfigurationManager.AppSettings["Sub"].ToString();
  5.     var library = ConfigurationManager.AppSettings["Library"].ToString();
  6.  
  7.     using (SPSite site = new SPSite(url))
  8.     {
  9.         using (SPWeb web = (sub == "*") ? site.RootWeb : site.OpenWeb(sub))
  10.         {
  11.             string docsetName = "Document Set Test";
  12.             SPContentType ctype = null;
  13.  
  14.             if (web.ContentTypes[docsetName] == null)
  15.             {
  16.                 // Creating the document set (content type)
  17.                 ctype = new SPContentType(web.ContentTypes["Document Set"], web.ContentTypes, "Document Set Test");
  18.                 ctype.FieldLinks.Add(new SPFieldLink(web.Fields["Author"]));
  19.                 ctype.Group = "Test Content Types";
  20.                 web.ContentTypes.Add(ctype);
  21.  
  22.                 // Getting the document set (content type)
  23.                 DocumentSetTemplate docsetTemplate = DocumentSetTemplate.GetDocumentSetTemplate(ctype);
  24.  
  25.                 // Setting the content types
  26.                 docsetTemplate.AllowedContentTypes.Remove(web.ContentTypes["Document"].Id);
  27.                 docsetTemplate.AllowedContentTypes.Add(web.ContentTypes["Word Template"].Id);
  28.                 docsetTemplate.AllowedContentTypes.Add(web.ContentTypes["Excel Spreadsheet Template"].Id);
  29.  
  30.                 // Sharing fields
  31.                 docsetTemplate.SharedFields.Add(web.Fields["Author"]);
  32.  
  33.                 // Displaying fields
  34.                 docsetTemplate.WelcomePageFields.Add(web.Fields["Author"]);
  35.  
  36.                 // Adding default document
  37.                 FileStream wordFile = File.OpenRead(Path.GetFullPath(@"DocumentSet\Default.dotx"));
  38.                 byte[] binWordFile = new byte[wordFile.Length];
  39.                 wordFile.Read(binWordFile, 0, binWordFile.Length);
  40.  
  41.                 docsetTemplate.DefaultDocuments.Add("Default.dotx", web.ContentTypes["Word Template"].Id, binWordFile);
  42.  
  43.                 // Updating the document set (content type),    
  44.                 docsetTemplate.Update(true);
  45.                 ctype.Update();
  46.             }
  47.  
  48.             ctype = ctype jQuery15207137137458194047_1344344305332 web.ContentTypes[docsetName];
  49.  
  50.             if (web.Lists.TryGetList(library) == null)
  51.             {
  52.                 // Creating document library
  53.                 Guid libraryGuid = web.Lists.Add(library, "", SPListTemplateType.DocumentLibrary);
  54.                 SPDocumentLibrary list = (SPDocumentLibrary)web.Lists[libraryGuid];
  55.  
  56.                 // Setting properties
  57.                 list.OnQuickLaunch = true;
  58.                 list.ContentTypesEnabled = true;
  59.                 list.EnableFolderCreation = false;
  60.  
  61.                 // Defining content types
  62.                 list.ContentTypes.Delete(list.ContentTypes["Document"].Id);
  63.                 list.ContentTypes.Add(ctype);
  64.                 list.Update();
  65.  
  66.                 System.Collections.Hashtable properties = new System.Collections.Hashtable();
  67.                 properties.Add("DocumentSetDescription", "Just an example"); //InternalName
  68.                 properties.Add("_Author", "MM"); //InternalName
  69.  
  70.                 // Creating the document set
  71.                 DocumentSet.Create(list.RootFolder, "DocSet1", list.ContentTypes.BestMatch(ctype.Id), properties, true);
  72.             }
  73.         }
  74.     }
  75. }

Note: A Document Library is created dynamically for demonstration purposes.

Download the solution here.

I hope it helps. Smile

References:
http://technet.microsoft.com/en-us/library/ff603637.aspx
http://office.microsoft.com/en-us/sharepoint-server-help/CH010372625.aspx
http://msdn.microsoft.com/en-us/library/ee574540.aspx

Cheers,

Marcel Medina

Click here to read the same content in Portuguese.

Comments (10) -

  • Anthony Nguyen

    7/29/2011 9:23:09 AM | Reply

    Thanks for your great sharing!

    Could you help me further with 2 questions:
    1. If the (Hashtable) properties contains some string like "<img src='abc.gif' width='10px' height='20px' />", the information of "src" will be removed after creating the Document Set (line 70 in your code). Is there any method to keep the src.

    2. How to update the (Hashtable) properties after the Document Set is created.

    Many thanks!

    • Marcel Medina

      11/3/2011 1:24:14 PM | Reply

      Hi Anthony,

      1) Try to use HttpUtility.HtmlEncode for that.

      2) The Hashtable is used as metadata to create the DocumentSet as a Folder. So if you want to get that, access the property DocumentSet.Folder.Properties. You will be able to do whatever you want with the methods AddProperty, DeleteProperty, SetProperty. More details check:
      msdn.microsoft.com/.../...nt.spfolder_members.aspx

      Cheers,

  • tsyselsky

    10/13/2011 2:56:43 AM | Reply

    tnx, it help.

  • waleed badawy

    2/3/2012 3:31:56 PM | Reply

    Thanks for your effort. That is exactly what I need.

  • Gary

    3/24/2012 2:37:55 AM | Reply


    Marcel, thanks for the wonderful code. It works as a Farm solution.  when I try it as Sandbox solution, it fails at DocumentSet.Create(...) ---  
    System.Security.SecurityException: That assembly does not allow partially trusted callers.  My AssemblyInfo.cs already has <assembly:AllowPartiallyTrustedCallers>.  Any suggestion?  Thanks again.

    • Dave

      6/25/2012 11:15:29 AM | Reply

      Hi Marcel, did you find a solution to the "That assembly does not allow partially trusted callers." error?
      Thanks

    • Marcel Medina

      6/25/2012 1:41:14 PM | Reply

      Hi Gary,

      If you open the class Microsoft.Office.DocumentManagement.DocumentSets.DocumentSet via ILSpy you will see that the method implementation calls some classes like SPSqlQueryCounter that is not supported in sandbox solutions:
      msdn.microsoft.com/.../...s.spsqlquerycounter.aspx

      Cheers,

      • Dave

        6/25/2012 1:45:26 PM | Reply

        So, based on this information Microsoft.Office.DocumentManagement.DocumentSets.DocumentSet is not suported in sandbox solutions. So would you suggest createing document sets the old way? As folders?

        • Marcel Medina

          6/25/2012 7:11:31 PM | Reply

          Hi Dave,

          You can create a full trust proxy to perform this operation from the sandbox. Have a look at this link:
          http://goo.gl/oC9pK

          Cheers,

  • carti

    8/9/2012 5:46:37 AM | Reply

    Thanks for the post.. Its really great.

    Can you tell how to get the document set versions using web services.

    It will be help..

    Thanks once again.

Loading