Although this question has been asked and answered, just thought of posting my findings so I can find it later.
ContentItem.Id
is indeed 0 when the content item isn't created yet. For example, when you're about to create a new Page, ContentItem.Id == 0
. Now just click on the Save button without filling up the form and validation will fail since the required field Title wasn't provided and we're getting back the same view with an error. Since validation failed, technically we don't consider the content item to be created yet. However, at this point Orchard already treating it as an existing content item. Orchard even went as far as obtaining and increasing the Identity counter of the Content Item Record table (Orchard_Framework_ContentItemRecord) from the database and assigning it as an Id to the content item.
Orchard even wired up all the Version Records, making it pretty much a full-fledged content item. All these for a content item that failed validation during creation and facing possibility of being discarded altogether. The only thing Orchard hasn't done is inserting it into the database (it's only residing in memory at this point). Therefore there's really no other ways to tell if a content item is an existing one or one that was about to be created other than checking it against the database and see if the content item was really there.
var contentItemRepository = _workContext.Resolve<IRepository<ContentItemRecord>>();
var contentItemRecord = contentItemRepository.Get(Model.ContentItem.Id);
if (contentItemRecord == null) {
isNew = true;
}
or we could also use the IContentManager
to do the same thing
var contentManager = Model.ContentItem.ContentManager;
var contentItem = contentManager.Get(Model.ContentItem.Id, VersionOptions.AllVersions);
if (contentItem == null) {
isNew = true;
}
Edit:
Apparently I spoke too soon. When I said above that Orchard hasn't inserted the content item into the database yet and it still resides in memory, it actually already in the database, in a yet to be committed Transaction. In the case above where validation fails, the transaction will be rolled back at the end. The correctness of the above code depends on when it was executed. If it was executed before the transaction was cancelled and rolled back, the content item is still in the database and won't yield an accurate result. If it was executed after transaction rollback (eg. in a View), then it'll behave as expected.
How Orchard handles content item creation can be seen in Orchard.Core.Contents.Controllers.AdminController.CreatePOST(string, string, Action<ContentItem>)
:
_contentManager.Create(contentItem, VersionOptions.Draft);
var model = _contentManager.UpdateEditor(contentItem, this);
if (!ModelState.IsValid) {
_transactionManager.Cancel();
return View(model);
}
The content item was being created first before it was being fed into IContentManager.UpdateEditor()
to validate.
Update:
Filed a bug at https://github.com/OrchardCMS/Orchard/issues/6534