Sunday, July 12, 2015

Configuring metadata defaults with CSOM

SharePoint folders have had it rough the last couple of years. The internet is full of 'folders are evil' posts, but in my view folders still have their uses. One of the interesting features SharePoint folders bring to the table is automatically setting metadata. Per folder you can configure which default values fields should have. This can be a great enabler when people don't want to tag documents manually.

We wanted to use this in a recent project where we had the requirement to provision and configure this from code. The metadata defaults objects however are only available in the full trust object model, and we build for SharePoint online. That leaves us with the puzzle of what actually happens when you configure metadata defaults and figuring out if we can do the same from CSOM. We found that metadata defaults functionality is implemented through two components:

  • The 'client_LocationBasedDefaults.html' file in the forms folder of the document library
  • A feature receiver bound to the same document library


The following screenshots are from an environment that's been configured manually. We have our document library 'Metadata'. This library has two folders, 'Yes' and 'No'. A choice field with the same options is added to the library and has been configured to be set automatically for files that are added to the folders.


With SharePoint designer we can view the contents of the 'client_LocationBasedDefaults.html'. It's basically a mapping of the folder (url), the field to be set, and the field value to be set. All this in a very simple XML structure.

The event receiver can be spotted using the great tool SharePoint Manager 2013. It's interesting to note that the event receiver is part of the "Microsoft.Office.DocumentManagement" namespace, the same namespace that gives us the Document Set which is also great folder and metadata tool.

Well, this doesn't appear to be to hard to do through CSOM! First we need to create the metadata file. The hidden forms folder in the library has the interesting property that you can add files to it just as you would do to any other folder. The following snippet is all you need:
// Creating the LocationBasedDefaults file in the forms folder. Will overwrite if it is already there.
var formsFolder = ctx.Web.GetFolderByServerRelativeUrl("/Metadata/Forms/");
var fci = new FileCreationInformation();
fci.Content = Encoding.UTF8.GetBytes("<MetadataDefaults><a href=\"/Metadata/No\"><DefaultValue FieldName=\"YesNo\">No</DefaultValue></a><a href=\"/Metadata/Yes\"><DefaultValue FieldName=\"YesNo\">Yes</DefaultValue></a></MetadataDefaults>");
fci.Url = "client_LocationBasedDefaults.html";
fci.Overwrite = true;
var metaDataFile = formsFolder.Files.Add(fci);

ctx.Load(metaDataFile);
ctx.ExecuteQuery();


After this we need to bind the out of the box event receiver. Note that we explicitly configure the event receiver to be synchronous. If you don't, the user will need to refresh the screen after dragging a document to the library to see the updated value. The following snippet has all the code required for this:
//Binding the OOTB event receiver
var list = ctx.Web.Lists.GetByTitle("Metadata");
var erci = new EventReceiverDefinitionCreationInformation();

erci.ReceiverName = "LocationBasedMetadataDefaultsReceiver ItemAdded";
erci.SequenceNumber = 1000;
erci.ReceiverClass = "Microsoft.Office.DocumentManagement.LocationBasedMetadataDefaultsReceiver";
erci.ReceiverAssembly = "Microsoft.Office.DocumentManagement, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";
erci.EventType = EventReceiverType.ItemAdded;
erci.Synchronization = EventReceiverSynchronization.Synchronous;

var receiver = list.EventReceivers.Add(erci);
ctx.Load(receiver);
ctx.ExecuteQuery();


And that's all there is to it. It's also possible to do this with Managed Metadata values. However, to get these to work you need to ensure they're already in the taxonomy hidden list on the site you are deploying this to. That's slightly out of scope for this write-up, but let me know if you run into trouble with that.

Attached: A full demo project for a provider hosted app which creates and configures a document library with managed metadata defaults.

Rating