This project is read-only.

How to cancel content delete from content part ContentHandler

Topics: Writing modules
Aug 23, 2012 at 5:07 PM
Edited Aug 23, 2012 at 5:09 PM
         public class CatalogHandler : ContentHandler {

             private readonly IOrchardServices _orchardServices;

             public CatalogHandler(IRepository<CatalogRecord> repository, IOrchardServices orchardServices)
                 _orchardServices = orchardServices;

                     (context, catalogPart) =>

                         var childs = _orchardServices.ContentManager.Query().ForPart<ProductPart>().Where<ProductRecord>(c => c.Catalog.Id == context.Id).Count();

                         if (childs > 0)
                             _orchardServices.Notifier.Error(new LocalizedString("Unable to remove item because have childs"));
                             var catalog = repository.Get(catalogPart.Id);





I'm doing that to stop the deletion of an content if it is related with another content part but dosent seem the best practices, how can i cancel a content deletion?

thank you anticipated, DM

Aug 25, 2012 at 4:07 AM
Edited Aug 25, 2012 at 4:08 AM

The best way in my opninion would be to add a property to the RemoveContentContext class called "Cancel". Then, the DefaultContentManager would check to see if that property has been set. If it has, then it will simply not unpublish the item. E.g.

public virtual void Remove(ContentItem contentItem) {
            var activeVersions = _contentItemVersionRepository.Fetch(x => x.ContentItemRecord == contentItem.Record && (x.Published || x.Latest));
            var context = new RemoveContentContext(contentItem);

            Handlers.Invoke(handler => handler.Removing(context), Logger);

            if( context.Cancel )

            foreach (var version in activeVersions) {
                if (version.Published) {
                    version.Published = false;
                if (version.Latest) {
                    version.Latest = false;

            Handlers.Invoke(handler => handler.Removed(context), Logger);

But instead of changing the core, you could instead derive a new class from ContentManager and override the Remove method and implement it as illustrated above. Use the OrchardSuppressDependency attribute to suppress the DefaultContentManager.


Aug 25, 2012 at 8:58 AM

Thank you for reply but if i do that i achieve the same result as my sample, the item isn't cancelled and the orchard emit the same message like delete operation was completed : "That [content name] has been removed." 

Each of this solution seems tricks, it must exist a way to cancel current "Action".


Aug 25, 2012 at 11:37 AM

This is no mere trick - it's real magic brother.

Ok, so in order to get what you want, the Remove method would have to provide a return value, say a RemoveResult object, indicating whether the item was actually deleted, or if the operation was cancelled, and perhaps a message string indicating why it was cancelled. The caller of the Remove method would then have to inspect the RemoveResult object and display the appropriate notification to the user.

If you want to cancel the current action, without casting some white magic, is to throw a black magic exception from within your handler.

Perhaps you could file a bug about this. I think it would be nice to be able to cancel the removal of items. We just need some mechanism for this.

Aug 27, 2012 at 7:52 AM

If i throw a "black magic exception" inside the handler anything happends this was the first 2cent solution.

I just need to understand how to manipulate the notify service to clear current notification.


Aug 28, 2012 at 11:05 PM
Edited Aug 28, 2012 at 11:05 PM

That would require adding a "Clear" method to INotifier.

Or, you could create your own Notifier class, implementing both INotifier and some sort of IResetableNotifier interface that has a "Clear" method.
Your custom implementation would basically be a copy of the Notifier class with the added method, decorated with an OrchardSuppressDependencyAttribute to suppress the default Notifier class.