Here’s a simple way to prevent users from deleting their assigned tasks (who would ever want to do that??).
Start by coding an ItemDeleting event receiver that cancels the attempt to delete the task.
If you want to drive your users crazy, you can just set the Status to CancelNoError.
Try it out first before you decide to go that route.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace SameNameSpaceAsTheRestOfYourWorkflow
{
class PreventWorkflowTaskDelete : SPItemEventReceiver
{
///
/// Prevent a workflow task from being deleted.
///
///
public override void ItemDeleting(SPItemEventProperties properties)
{
string errorMessage = string.Empty;
try
{
errorMessage = string.Format("User {0} is not allowed to delete this Task.", properties.UserDisplayName);
}
catch
{
errorMessage = "You are not allowed to delete a task.";
}
finally
{
properties.ErrorMessage = errorMessage;
}
properties.Cancel = true;
properties.Status = SPEventReceiverStatus.CancelWithError;
}
}
}Next, when your workflow starts, call a method similar to the following to register the custom event receiver.
My example includes calls to my custom trace feature, so you’ll have to eliminate them before you can use this code.
#region PreventWorkflowTaskDeletion
///
/// Prevent workflow tasks from being deleted by adding an event receiver that will cancel any
/// attempt to delete a task from the workflow task list.
///
private void PreventWorkflowTaskDeletion()
{
string methodName = MethodBase.GetCurrentMethod().Name;
TraceEnter(methodName);
string message = string.Empty;
// prevent multiple ItemDeleting event receivers from being attached to the task list by removing any that may already exist.
// NOTE: has the added benefit of replacing existing event receiver if we made a code change and redeployed recently.
SPEventReceiverDefinitionCollection evrs = workflowProperties.Workflow.TaskList.EventReceivers;
List ersToDelete = new List();
foreach (SPEventReceiverDefinition er in evrs)
{
if (er.Type == SPEventReceiverType.ItemDeleting)
{
// add the GUID index of the Event Receiver to the list of ones we need to get rid of
ersToDelete.Add(er.Id);
}
}
// have to wait until outside of the above loop to delete; otherwise, you get this error:
// System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
foreach (Guid i in ersToDelete)
{
message = string.Format("Removed ItemDeleting event reciever with GUID of {0}", i.ToString());
TraceInfo(message);
evrs[i].Delete();
workflowProperties.Workflow.TaskList.Update();
}
// Example: "Microsoft.Office.Samples.ECM.Workflow.ReplicatorContactSelectorSample, Version=3.0.0.0, Culture=neutral, PublicKeyToken=ec457ebe7d96977c";
string assembly = Assembly.GetExecutingAssembly().FullName;
message = string.Format("assembly = {0}", assembly);
TraceInfo(message);
// Example: "Microsoft.Office.Samples.ECM.Workflow.PreventWorkflowTaskDelete";
string className = typeof(PreventWorkflowTaskDelete).FullName;
message = string.Format("className = {0}", className);
TraceInfo(message);
// add the ItemDeleting event receiver to the current workflow task list
try
{
workflowProperties.Workflow.TaskList.EventReceivers.Add(SPEventReceiverType.ItemDeleting, assembly, className);
workflowProperties.Workflow.TaskList.Update();
message = string.Format("Added ItemDeleting event");
}
catch (Exception ex)
{
message = string.Format("ERROR: Method {0} had an exception while attempting workflowProperties.Workflow.TaskList.EventReceivers.Add : {0}", ex.Message);
TraceError(message);
throw new SPException(message);
}
finally
{
TraceInfo(message);
}
}
#endregionIn the above code, I was making frequent changes to the event receiver, thus the need to remove and re-add the event receiver each time.