After a folder gets copied to a new location in SharePoint, the default values do not get synchronized to the folder's child files and folders. I am attempting to set the default values on these child files and folders using the default values already set at the folder level (as defined in Settings > Change Default Column Values) for this targetFolder.
public async Task SyncDefaultMetaDataAsync(IFolder targetFolder)
{
var queue = new Queue();
queue.Enqueue(targetFolder);
var list = await _sharePointContext.Web.Lists.GetByServerRelativeUrlAsync(targetFolder.ServerRelativeUrl);
var defaultColumnValues = await list.GetDefaultColumnValuesAsync();
while (queue.Count > 0)
{
var item = queue.Dequeue();
switch (item)
{
case IFile file:
{
await file.LoadAsync(f => f.ServerRelativeUrl, f => f.ListItemAllFields);
foreach (var defaultColumnValue in defaultColumnValues)
{
file.ListItemAllFields[defaultColumnValue.FieldInternalName] = defaultColumnValue.DefaultValue;
}
var relativeFilePathUrl = file.ServerRelativeUrl.Replace(targetFolder.ServerRelativeUrl, string.Empty);
_logger.LogInformation($"Updating folder fields on: {relativeFilePathUrl}");
await file.ListItemAllFields.UpdateAsync();
break;
}
case IFolder folder:
{
await folder.LoadAsync(f => f.ServerRelativeUrl, f => f.Files, f => f.Folders, f => f.ListItemAllFields);
folder.Folders.AsRequested().ToList().ForEach(childFolder => queue.Enqueue(childFolder));
folder.Files.AsRequested().ToList().ForEach(childFile => queue.Enqueue(childFile));
foreach (var defaultColumnValue in defaultColumnValues)
{
folder.ListItemAllFields[defaultColumnValue.FieldInternalName] = defaultColumnValue.DefaultValue;
}
var relativeFilePathUrl = folder.ServerRelativeUrl.Replace(targetFolder.ServerRelativeUrl, string.Empty);
_logger.LogInformation($"Updating folder fields on: {relativeFilePathUrl}");
await folder.ListItemAllFields.UpdateAsync();
break;
}
}
}
}
This code produces this error:
crit: Microsoft.Extensions.Hosting.Internal.Host[10]
The HostOptions.BackgroundServiceExceptionBehavior is configured to StopHost. A BackgroundService has thrown an unhandled exception, and the IHost instance is stopping. To avoid this behavior, configure this to Ignore; however the BackgroundService will not be restarted.
HttpResponseCode: 400
Code: System.ArgumentException
Message: Column 'Location_City' does not exist. It may have been deleted by another user. /sites/MySite/MyDocLibrary
ClientRequestId: 4cecb9a0-50ae-3000-9905-af7dacb867db
SPClientServiceRequestDuration: 47
X-SharePointHealthScore: 0
X-SP-SERVERSTATE: ReadOnly=0
PnP.Core.SharePointRestServiceException: SharePoint Rest service exception
at PnP.Core.Services.BatchClient.ExecuteSharePointRestInteractiveAsync(Batch batch)
at PnP.Core.Services.BatchClient.ExecuteSharePointRestBatchAsync(Batch batch)
at PnP.Core.Services.BatchClient.ExecuteBatch(Batch batch)
at PnP.Core.Model.SharePoint.ListItem.BaseUpdate(Func`2 fromJsonCasting, Action`1 postMappingJson)
at PnP.Core.Model.BaseDataModel`1.UpdateAsync()
at BigCorp.MyProject.Worker.SyncDefaultMetaDataAsync(IFolder targetFolder) in C:\Source\BigCorp.MyProject\Worker.cs:line 123
at BigCorp.MyProject.Worker.ExecuteAsync(CancellationToken stoppingToken) in C:\Source\BigCorp.MyProject\Worker.cs:line 64
at Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService backgroundService)
I have confirmed the Location_City field exists in Settings > List Content Type screen and I would have thought calling list.GetDefaultColumnValuesAsync() to retrieve the default values already available would guarantee their presence since I am not manually assigning these field values.
Also, I would be interested if there is a more efficient way to set the default values for all the files and folders inside this target folder (including all child folders and files) without having to iterate over all of them?