If you try to save some published content with the ForceCurrentVersion flag set, it will fail in seemingly illogical cases. For instance:
contentRepository.Save(publishedPage, SaveAction.ForceCurrentVersion);
will result in the error:
ERROR: The provided action 'ForceCurrentVersion' is not allowed on this content (ContentLink=257864_794789, VersionStatus=Published)
However, if I add SaveAction.Publish, this runs just fine:
contentRepository.Save(publishedPage, SaveAction.Publish | SaveAction.ForceCurrentVersion)
Is there some logic to this?
Why am I asking?
Before upgrading to the newest version of EPiServer the following code worked great both for published and unpublished content:
// On the CreatedContent event
MakeTheShortUrlLowerCase(writablePage);
// Save without creating a new version:
contentRepository.Save(writablePage, SaveAction.ForceCurrentVersion | SaveAction.SkipValidation);
But after the upgrade, the behaviour of the Save function seem to have changed. In order to get it working again, we had to complicate the code with an additional check for published content:
// On the CreatedContent event
MakeTheShortUrlLowerCase(writablePage);
// Check if published, then select save alternative
if (pageData.CheckPublishedStatus(PagePublishedStatus.PublishedIgnoreDates))
{
contentRepository.Save(writablePage, SaveAction.Publish | SaveAction.ForceCurrentVersion | SaveAction.SkipValidation);
}
else
{
contentRepository.Save(writablePage, SaveAction.ForceCurrentVersion | SaveAction.SkipValidation);
}
To me, this "fix" seems somewhat unnecessary, and really doesn't make a lot of sense.
Update
For future reference, here is what I ended up doing: I implemented a simple helper class to handle cases where ForceCurrentVersion is used:
private static SaveAction GetForcedSaveActionFor(IVersionable page)
{
var saveAction = SaveAction.SkipValidation | SaveAction.ForceCurrentVersion;
switch (page.Status)
{
case VersionStatus.Published:
saveAction = saveAction | SaveAction.Publish;
break;
case VersionStatus.CheckedIn:
saveAction = saveAction | SaveAction.CheckIn;
break;
default:
saveAction = saveAction | SaveAction.Save;
break;
}
return saveAction;
}
Which then could be used as follows:
var saveAction = GetForcedSaveActionFor(pageData);
contentRepository.Save(writablePage, saveAction);
This naturally does not cover all cases of VersionStatus, but you get the idea.
The SaveActions enumeration has a somewhat unorthodox split where some of the values represents the primary command (Save, Publish, CheckIn, etc) and some of the values represents different options (ForceCurrentVersion, SkipValidation).
When passing only options flag to the Save method, you are in essence only passing options without any command. Previously a best effort approach was used to find out which command that was going to be used in case no command was provided, but it turned out that this was not very predictable in a lot of cases and it also caused content to be published without Publishing events being raised and publishing specific validation to be done.
An attempt to improve the situation was made for CMS 8 and you are now required to provide a SaveAction that includes the primary command when updating published content. This unfortunately had the side effect that you found in which you needed to be more explicit about which SaveAction command that should be used. Hopefully you will be able to hide the evaluation behind a utility method.
The current solution is leaving a lot to wish for in terms of usability and there are still edge-case irregularities that remain in this code, but as it is very difficult to make any improvements here without making breaking changes, the progress can be slow.
The answer above only applies for Episerver CMS version 9. This behavior has been changed in CMS 10 and SaveAction.ForceCurrentVersion
now works on it's own without the need to combine it with another action. See this CMS 10 release note for detailed information on this update.