HOW TO: Access list item in WorkflowStarting event receiver when “Required documents to be checked out” option is set to “Yes”

This post is a contribution from Charls Tom Jacob, an engineer with the SharePoint Developer Support team.

Scenario:

You have a SharePoint library in which “Require documents to be checked out before they can be edited?” is set to Yes. You have a WorkflowStarting event receiver associated to the list, with the following very basic implementation:

 public override void WorkflowStarting(SPWorkflowEventProperties properties)
 {
     SPList list = properties.ActivationProperties.List;
     int id = properties.ActivationProperties.ItemId;
     SPListItem currentitem = list.GetItemById(id);
 }

Issue:

When the event receiver is triggered, the above code will fail with the following exception while getting the item:

 ArgumentException was unhandled by user code: Item does not exist. It may have been deleted by another user.
  
 at Microsoft.SharePoint.SPList.GetItemById(String strId, Int32 id, String strRootFolder, Boolean cacheRowsetAndId, String strViewFields, Boolean bDatesInUtc)
 at Microsoft.SharePoint.SPList.GetItemById(Int32 id)
 at WorkflowEventTest.EventReceiver1.EventReceiver1.WorkflowStarting(SPWorkflowEventProperties properties)
 at Microsoft.SharePoint.Workflow.SPWorkflowEventManager.RunWorkflowEventReceiverHelper(Object receiver, SPUserCodeInfo userCodeInfo, Object properties, SPEventContext context, String receiverData)
 at Microsoft.SharePoint.SPEventManager.<>c__DisplayClassc`1.<InvokeEventReceivers>b__6()
 at Microsoft.SharePoint.SPSecurity.RunAsUser(SPUserToken userToken, Boolean bResetContext, WaitCallback code, Object param)

Reason:

When “Require documents to be checked out before they can be edited?” is set to Yes, the uploaded item gets exclusively checked out to the user who uploaded it. This means item won’t be viewable/accessible to ANY other user. This is because the workflow starting event is triggered way before the upload process is fully complete. When “Require documents to be checked out ” is Yes, user is presented with an additional page which says “The document was uploaded successfully and is checked out to you. Check that the fields below are correct and that all required fields are filled out. The file will not be accessible to other users until you check in.”

image

Event receiver executes while the user is presented with this popup screen, and it executes in the context of SHAREPOINT\SYSTEM account and runs into this error.

NOTE: Exclusive checkout applies to another scenario, where the user uploads the document but cancels the check-in popup; The document remains checked out and accessible only to the same user.

Solution: Impersonate the user account while accessing the list item.

 public override void WorkflowStarting(SPWorkflowEventProperties properties)
 {
     base.WorkflowStarting(properties);
     SPUserToken token = properties.ActivationProperties.Web.AllUsers[properties.ActivationProperties.Originator].UserToken;
     SPSite site = new SPSite(properties.ActivationProperties.Web.Url, token);
     SPWeb web = site.OpenWeb();
     SPList list = web.Lists[properties.ActivationProperties.ListId];
     SPListItem item = list.GetItemById(properties.ActivationProperties.ItemId);
 }

With the above code, item is accessed using the same user account which was used to upload the document, hence the code succeeds in getting the item.

Hope this information was helpful!