November Happy Hour will be moved to Thursday December 5th.

ContentNotFoundException while trying to creating a copy of a "template-page"

Vote:
 

Hello,

our requirement is to create a copy of  a master/template page every day and to let editors add the content to each block in a so called "admin-ui". Therefore i'm trying to create a copy of the template-page and then return the editable blocks of that page. But while it is working to copy the template to the same folder(it gets the name "Daily TG Master(2)"), i get a ContentNotFoundException if i use ContentRepository.Copy. I don't know what can be the reason if the CMS can copy it without a problem. This is the exception:

EPiServer.Core.ContentNotFoundException: 'Content with id 60991__articleoverviewprovider20068 was not found'

This exception was originally thrown at this call stack:
    EPiServer.Core.Internal.DefaultContentLoader.Get<T>(EPiServer.Core.ContentReference, EPiServer.Core.LoaderOptions)
    EPiServer.Core.Transfer.Internal.BlobTransfer.TryAddFile(string, out string)
    EPiServer.Core.Transfer.Internal.MultiplexingFileTransfer.TryAddFile(string, out string)
    EPiServer.Core.Transfer.Internal.PropertyXhtmlTransform.ExportLinksAndAddFiles(string, EPiServer.Core.Transfer.IContentTransferContext)
    EPiServer.Core.Transfer.Internal.PropertyXhtmlTransform.ExportFragments(EPiServer.Core.Html.StringParsing.StringFragmentCollection, EPiServer.Core.Transfer.IContentTransferContext)
    EPiServer.Core.Transfer.Internal.PropertyXhtmlTransform.TransformForExport(EPiServer.SpecializedProperties.PropertyXhtmlString, EPiServer.Core.RawProperty, EPiServer.Core.Transfer.PropertyExportContext)
    EPiServer.Core.Transfer.Internal.DefaultPropertyExporter.RunTransforms(EPiServer.Core.PropertyData, EPiServer.Core.RawProperty, EPiServer.Core.Transfer.PropertyExportContext)
    EPiServer.Core.Transfer.Internal.DefaultPropertyExporter.ExportProperty(EPiServer.Core.PropertyData, EPiServer.Core.RawProperty, EPiServer.Core.Transfer.PropertyExportContext)
    EPiServer.Core.Transfer.Internal.DefaultPropertyExporter.ExportProperties(EPiServer.Core.IContentData, System.Collections.Generic.IEnumerable<EPiServer.Core.RawProperty>, EPiServer.Core.Transfer.PropertyExportContext)
    EPiServer.Core.Transfer.Internal.DefaultContentExporter.Export(EPiServer.Core.IContent, EPiServer.Security.AccessLevel, EPiServer.Core.Transfer.IContentTransferContext, EPiServer.Core.Transfer.TransferExportOptions)
    ...
    [Call Stack Truncated]

Here's the relevant code:

private DailyTelegramPage CreateTelegramPageCopyFromTemplate()
{
	try
	{
		if (!_contentRepository.TryGet(_references.TemplateReference, new LoaderOptions() { LanguageLoaderOption.FallbackWithMaster() }, out DailyTelegramPage templatePage))
		{
			this.LogError($"Could not load daily telegram template page '{_references.TemplateReference}'");
			return null;
		};

		ContentReference copy = _contentRepository.Copy(templatePage.ContentLink, _references.RootReference,
			AccessLevel.NoAccess, AccessLevel.NoAccess, false);
		if (!_contentRepository.TryGet(copy, new LoaderOptions() { LanguageLoaderOption.FallbackWithMaster() }, out DailyTelegramPage createdCopy))
		{
			this.LogError($"Could not load created template copy. Template '{_references.TemplateReference}' Copy '{copy}");
			return null;
		}

		DailyTelegramPage writableCopy = (DailyTelegramPage)createdCopy.CreateWritableClone();
		writableCopy.Name = "Daily TG " + DateTime.Today.ToString("yyyyMMdd");
		writableCopy.URLSegment = _urlSegmentGenerator.Create(writableCopy.Name);
		writableCopy.ParentLink = _references.RootReference;
		writableCopy.ArchiveLink = _references.ArchiveReference;
		writableCopy.StopPublish = DateTime.Today.AddDays(1);
		writableCopy.NoIndex = true;
		writableCopy.NoFollow = true;
		ContentReference saveRef = _contentRepository.SaveContentToPublishWithNoAccess(writableCopy);
		if (saveRef?.Equals(writableCopy.ContentLink, true) != true)
		{
			this.LogError($"Created daily telegram page has multiple ContentReferences: <{saveRef?.ID}> and <{writableCopy.ContentLink?.ID}>");
		}

		return createdCopy;
	}
	catch (Exception ex)
	{
		this.LogError(ex, $"Error on creating daily telegram page copy from template. Template-ID:{_references.TemplateReference.ID} Root-ID:{_references.RootReference.ID}");
		return null;
	}
}

That 60991__articleoverviewprovider20068 is an article-page which just exists in memory because we have a ContentProvider for articles. They exists at one place("Article Management") but in the cms-tree they can be added in several places("Article-Blogs"). I don't know if that's related. But the copy in cms works without a problem.

#303740
Jun 19, 2023 7:52
Vote:
 

Hi Tim,

Have you looked at  the Copy method upon the ContentProvider?

Paul

#303741
Jun 19, 2023 8:15
Tim Schmelter - Jun 19, 2023 10:30
Hi Paul. Thanks. But actually this is a so called DailyTelgramPage and i want to copy the whole content to a new page-copy. It has a ContentArea property where the editor can drop arbitrary content. So i guess i have to use ContentRepository.Copy (because it's not a ContentProvider). Just the exception was suggesting that it might be related to an article(couldn't find in the content) that could not be copied because the ContentReference is created from the ContentProvider and it doesn't exist in database.
Vote:
 

Hi Tim,

I took your code and did a little modification as I think you have an extension method 'SaveContentToPublishWithNoAccess'. I have also removed out some of your custom properties, essentially this does the littliest work possible as all this is supposed to do is copy the template.

private ContentReference CreateCopyFromTemplate(ContentReference source, ContentReference destination)
        {

            if (!_contentRepository.TryGet(source, new LoaderOptions() { LanguageLoaderOption.FallbackWithMaster() }, out PageData templatePage))
            {
                return null;
            };

            ContentReference copy = _contentRepository.Copy(templatePage.ContentLink, destination,
                AccessLevel.NoAccess, AccessLevel.NoAccess, false);
            if (!_contentRepository.TryGet(copy, new LoaderOptions() { LanguageLoaderOption.FallbackWithMaster() }, out PageData createdCopy))
            {
                return null;
            }

            StartPage writableCopy = (StartPage)createdCopy.CreateWritableClone();
            writableCopy.Name = "Daily TG " + DateTime.Today.ToString("yyyyMMdd");
            writableCopy.StopPublish = DateTime.Today.AddDays(1);

            ContentReference saveRef = _contentRepository.Save(writableCopy, EPiServer.DataAccess.SaveAction.Publish, AccessLevel.NoAccess);



            return saveRef;

        }

Now that we have the reference to the page we can implement a second method to modify the properties you want to update.

private ContentReference UpdateTemplate(ContentReference reference, PageReference parentLink, PageReference archiveLink)
        {

            if (!_contentRepository.TryGet(reference, new LoaderOptions() { LanguageLoaderOption.FallbackWithMaster() }, out PageData templatePage))
            {
                return null;
            };

            StartPage writableCopy = (StartPage)templatePage.CreateWritableClone();
            writableCopy.URLSegment = _urlSegmentGenerator.Create(writableCopy.Name);
            writableCopy.ParentLink = parentLink;
            writableCopy.ArchiveLink = archiveLink;
            writableCopy.NoIndex = true;
            writableCopy.NoFollow = true;

            ContentReference saveRef = _contentRepository.Save(writableCopy, EPiServer.DataAccess.SaveAction.Publish, AccessLevel.NoAccess);

            return saveRef;

        }

If you get the reference pack in the first method then the issue doesn't appear to be copying and creating the page template, and is more something updating the template. I do remember having issues generating urls in the past will take a look and see what I can dig out on that one.

Paul

#303750
Jun 19, 2023 12:36
Tim Schmelter - Jun 19, 2023 14:44
Thanks Paul. But the ContentNotFoundException happens at _contentRepository.Copy, so it doesn't help to update the page in a different method. Anyway, thanks for the help. I will try to find a workaround for the issue. Just strange that i don't get the exception if i copy the page in the CMS.
Vote:
 

Hi Tim,

The copy code I put into an alloy site so your code does work.

What I did notice however is that when i used the start page it copied the whole tree.

Is it possible you have a broken link in the template structure and that is causing the problem?

Paul

#303800
Jun 20, 2023 9:16
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.