Prevent deleting workflow task

When we create a workflow, we use workflow task (0x010801) to communicate with the users (make decision, collect data, set variables…).  The instance of the workflow waits this task until passing to complete.  The problem is when a SharePoint user deletes this task, then we will have a zombie workflow instance (never finished).
To resolve this problem we have two solutions:

First solution at in the workflow definition, we create a “Task Deleted” activity and we stop the instance of the workflow.
The second solution is to prevent users to delete any tasks waited by any instance of workflow.  I recommend the second solution because is more generic.
To implement this solution we create an Event Receiver, and we check the task item. If she is an instance of workflow we prevent deleting and we show a message to the user.

Key words:
0x010801: the code of the content type “WorkflowTask”
SPBuiltInFieldId.WorkflowName: define the name of the workflow owner of the task.

public override void ItemDeleting(SPItemEventProperties properties)
SPListItem taskItem = properties.ListItem;//task to deleted
 if (taskItem.ContentTypeId.Parent.Parent.ToString() == "0×010801")
string workflowName = taskItem[SPBuiltInFieldId.WorkflowName].ToString();
 SPList list=properties.Web.Lists[new Guid(taskItem[SPBuiltInFieldId.WorkflowListId].ToString())];
SPListItem item = list.GetItemById(int.Parse(taskItem[SPBuiltInFieldId.WorkflowItemId].ToString()));
foreach (SPWorkflow myWorkflow in item.Workflows)
if (list.WorkflowAssociations[myWorkflow.AssociationId].Name == workflowName && myWorkflow.InternalState == SPWorkflowState.Running){
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = string.Format("You can’t delete this task:the workflow <a href=’{0}’> {1}</a> associated to the element <a href=’{2}’>{3}</a> in the list <a href=’{4}’>{5}</a>,is running<br/>",properties.WebUrl+"/"+ myWorkflow.StatusUrl, workflowName, properties.WebUrl+"/"+item.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url+"?id="+item.ID.ToString(), item.Name, list.DefaultViewUrl, list.Title);
properties.Cancel = true;


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s