Working with Document Sets
A Document Set is a group of related documents that you can manage as a single entity. Looking at it's implementation a Document Set is based upon content types, it's a special content type with some specific Document Set settings.
In the remainder of this article you'll see a lot of context use: in this case this is a PnPContext which was obtained via the PnPContextFactory as explained in the overview article and show below:
using (var context = await pnpContextFactory.CreateAsync("SiteToWorkWith"))
{
// See next chapter on how to use the PnPContext for working with content types
}
Loading a content type as Document Set
All Document Sets in need to inherit from the base Document Set content type, which has as content type id 0x0120D520. To access the Document Set functionality for an existing content type you first need to load it as a Document Set via one of the AsDocumentSet methods.
// Load the base Document Set content type
IContentType contentType = await (from ct in context.Web.ContentTypes
where ct.StringId == "0x0120D520"
select ct)
.QueryProperties(ct => ct.StringId, ct => ct.Id)
.FirstOrDefaultAsync();
var documentSet = await contentType.AsDocumentSetAsync();
// check the settings
foreach(var sharedColumn in documentSet.SharedColumns)
{
}
Adding a Document Set
To add a new Document Set you can use one of the AddDocumentSet methods on the IContentTypeCollection you're working with. While doing so you can provide the specific Document Set configuration via an DocumentSetOptions instance as shown in below sample.
// Load the needed fields that will serve as Shared Field or Welcome Field in the Document Set
var categoriesField = await context.Web.Fields.FirstAsync(y => y.InternalName == "Categories").ConfigureAwait(false);
var managersField = await context.Web.Fields.FirstAsync(y => y.InternalName == "ManagersName").ConfigureAwait(false);
// Load the content types that are allowed to be added to the Document Set
var documentCt = await context.Web.ContentTypes.FirstAsync(y => y.Name == "Document").ConfigureAwait(false);
var formCt = await context.Web.ContentTypes.FirstAsync(y => y.Name == "Form").ConfigureAwait(false);
// Load the template files that will be used as default content for the Document Set
var file = await context.Web.GetFileByServerRelativeUrlAsync("/sites/hrsite/cv/template.docx").ConfigureAwait(false);
// Prepare the Document Set options
var documentSetOptions = new DocumentSetOptions
{
AllowedContentTypes = new List<IContentType>
{
documentCt,
formCt
},
ShouldPrefixNameToFile = true,
PropagateWelcomePageChanges = true,
SharedColumns = new List<IField>
{
managersField,
categoriesField
},
WelcomePageColumns = new List<IField>
{
managersField,
categoriesField
},
DefaultContents = new List<DocumentSetContentOptions>
{
new DocumentSetContentOptions
{
FileName = "template.docx",
FolderName = "Templates",
File = file,
ContentTypeId = documentCt.StringId
}
}
};
// Create the Document Set
IDocumentSet newDocumentSet = await context.Web.ContentTypes.AddDocumentSetAsync(docSetId, "My New Document Set", "", "Custom Document Sets", documentSetOptions);
Updating a Document Set
Updating a Document Set is fairly similar to adding one, first you ensure you've an IDocumentSet instance for the Document Set you want to update, followed by passing in the specific Document Set configuration via an DocumentSetOptions instance which is applied via a call to one of the Update methods.
IContentType contentType = await (from ct in context.Web.ContentTypes
where ct.Name == "My New Document Set"
select ct)
.QueryProperties(ct => ct.StringId, ct => ct.Id)
.FirstOrDefaultAsync();
var documentSet = await contentType.AsDocumentSetAsync();
// Load the needed fields that will serve as Shared Field or Welcome Field in the Document Set
var managersField = await context.Web.Fields.FirstAsync(y => y.InternalName == "ManagersName").ConfigureAwait(false);
// Load the template files that will be used as default content for the Document Set
var file = await context.Web.GetFileByServerRelativeUrlAsync("/sites/hrsite/cv/template2.docx").ConfigureAwait(false);
// Prepare the Document Set options
var documentSetOptionsUpdate = new DocumentSetOptions
{
SharedColumns = new List<IField>
{
managersField
},
WelcomePageColumns = new List<IField>
{
managersField
},
DefaultContents = new List<DocumentSetContentOptions>
{
new DocumentSetContentOptions
{
FileName = "template2.docx",
FolderName = "Templates",
File = file,
ContentTypeId = documentCt.StringId
}
}
};
// Update the Document Set
documentSet = await documentSet.UpdateAsync(documentSetOptionsUpdate);
Deleting a Document Set
Given a Document Set is a content type, deleting a Document Set is identical to deleting a content type. If you have an IDocumentSet reference you obtain the connected content type via the Parent property and once you have that you can delete the Document Set content type.
// Option A: directly delete the Document Set content type
IContentType contentType = await (from ct in context.Web.ContentTypes
where ct.Name == "My New Document Set"
select ct)
.QueryProperties(ct => ct.StringId, ct => ct.Id)
.FirstOrDefaultAsync();
await contentType.DeleteAsync();
// Option B: start from an IDocumentSet
// Assume IDocumentSet newDocumentSet is set
var contentType = newDocumentSet.Parent as IContentType
await contentType.DeleteAsync();
Note
If a content type is in use you cannot delete it.