Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
AI OnAI Off
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
I saw there was already a reported post about this initialization module but I think the problem I got is slightly different. This other report is found here: https://world.optimizely.com/forum/developer-forum/Problems-and-bugs/Thread-Container/2024/8/episerver-forms-5-7-2-and-newer-crashes-on-initialization/
My stacktrace was:
In MigrationService.cs the code is iterating all upload asset folder owned by a content that inherits IFileUploadElementBlock by checking ContentOwnerID.
if (contentAssetFolder != null && !(contentAssetFolder.ContentOwnerID == Guid.Empty) && this._contentRepository.Service.Get<IContent>(contentAssetFolder.ContentOwnerID) is IFileUploadElementBlock)
However the if statement uses IContentRepository.Get instead of IContentRepository.TryGet and in my case the owner content must have been deleted because this is where the code throws exception.
The fix for this is pretty simple thought. I created my own version of MigrationService.cs
public class MigrationServiceWithTryGet : MigrationService { private Injected<IContentTypeRepository> _contentTypeRepository; private Injected<IContentRepository> _contentRepository; private Injected<IContentModelUsage> _contentModelUsage; private Injected<IContentSecurityRepository> _contentSecurityRepository; public override void UpdateMissingUploadFolderACL() { var contentFolderType = _contentTypeRepository.Service.Load<ContentFolder>(); var contents = _contentModelUsage.Service.ListContentOfContentType(contentFolderType); var contentReferences = contents.Select(x => x.ContentLink.ToReferenceWithoutVersion()).Distinct(); foreach (var contentLink in contentReferences) { var contentFolder = _contentRepository.Service.Get<ContentFolder>(contentLink); if (contentFolder != null && (object)contentFolder.ParentLink != null && contentFolder.Name == "Uploaded Files") { var contentAssetFolder = _contentRepository.Service.Get<ContentAssetFolder>(contentFolder.ParentLink); if (contentAssetFolder != null && !(contentAssetFolder.ContentOwnerID == Guid.Empty) && // The 'TryGet' instead of just 'Get' is the difference between this and the optimizely original code _contentRepository.Service.TryGet<IContent>(contentAssetFolder.ContentOwnerID, out var fileUploadElementBlock) && fileUploadElementBlock is IFileUploadElementBlock) { IContentSecurityDescriptor securityDescriptor = contentFolder.GetContentSecurityDescriptor(); ContentAccessControlList contentSecurityDescriptor = []; if (securityDescriptor.Entries.Any(entry => entry.Name.Equals(EveryoneRole.RoleName, StringComparison.OrdinalIgnoreCase))) { foreach (AccessControlEntry entry in securityDescriptor.Entries) { if (!entry.Name.Equals(EveryoneRole.RoleName, StringComparison.OrdinalIgnoreCase)) contentSecurityDescriptor.Add(entry); } _contentSecurityRepository.Service.Save(contentFolder.ContentLink, contentSecurityDescriptor, SecuritySaveType.Replace); } } } } } }
And then forwarded the original service to my own in Startup.cs