I am attempting to set default values for columns in a document list in SharePoint using the PnP.Core SDK. I can successfully set the values and then query them and get the default values back:
private async Task SetFolderDefaultValues(IFolder folder, MyEvent event)
{
var defaultColumnValues = new List<DefaultColumnValueOptions>()
{
new()
{
FolderRelativePath = folder.ServerRelativeUrl,
FieldInternalName = "Project_Number",
DefaultValue = event.ProjectId
},
// ... other properties
};
var list = await _sharePointContext.Web.Lists.GetByServerRelativeUrlAsync(WorkingDirectoryRootRelativePath);
await list.SetDefaultColumnValuesAsync(defaultColumnValues);
var loadedDefaults = await list.GetDefaultColumnValuesAsync(); // Success! This contains the values I just set.
}
The problem is whenever I upload a new file anywhere inside this folder, the file does not contain the default values that were set with that code. I also looked in the settings located at /sites/MySite/_layouts/15/ColumnDefaults.aspx
and found the default value column doesn't contain the default values I set even though they come back in that GetDefaultColumnValuesAsync()
call successfully.
How do I set default column values for a specific folder using the Pnp.Core SDK?
I figured it out. A subtle thing I missed in the PnP.Core docs for the section on Setting default values is that the folder paths are relative to the list and not to the server when setting the FolderRelativeUrl for the individual options. So make sure your path is correct and that will mitigate the 404 `FileNotFoundException. It's a subtle difference but the naming of the property gives a hint.
However, I decided to approach it slightly different and just get the existing columns first and then set default values on the folder and updating any values I had for those columns. This allowed me to ignore the paths altogether.
private async Task SetFolderDefaultValues(IFolder folder, MyData data)
{
var list = await _sharePointContext.Web.Lists.GetByServerRelativeUrlAsync(folder.ServerRelativeUrl);
var existingColumns = await list.GetDefaultColumnValuesAsync();
// Ensure we only have a unique set of columns
existingColumns = existingColumns.GroupBy(obj => obj.FieldInternalName)
.Select(group => group.First())
.ToList();
foreach (var existingColumn in existingColumns)
{
switch (existingColumn.FieldInternalName)
{
case "Project_Number":
existingColumn.DefaultValue = data.ProjectId;
break;
case "Project_Description":
existingColumn.DefaultValue = data.ProjectName;
break;
}
}
await list.SetDefaultColumnValuesAsync(existingColumns);
}