Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have a workflow running when an item is adding to a document library. In this workflow, I have a code activity that I am attempting to set permissions to the list item. I am trying to break inheritance, and set some specific permissions. I've done this before so I'm not concerned with the code for this.

The issue that I am running in to is when checking the item back in to SharePoint. When I run checkin, I get the generic error saying The security validation for this page is invalid. There is no exception thrown in the code and I can step over it without issue. However, after this code block, the error is in the logs and the workflow says Failed to start (retrying). This workflow has worked numerous times prior to me adding this code activity.

Here is the code block I am working with (simplified, but non-functioning):

workflowProperties.Web.AllowUnsafeUpdates = true;
SPListItem item = workflowProperties.Item;
item.File.CheckOut();
item.BreakRoleInheritance(false);
item.SystemUpdate(false);
item.File.CheckIn("permissions updated");
workflowProperties.Web.AllowUnsafeUpdates = false;

Any ideas? I've tried running an UndoCheckout() on the File, but the same result occurs.

Edit 1

The reason I was performing the checkout is that I found my workflow would end up with 'Failed on start (retrying)' after the item permissions have been set. The logs say

Microsoft.SharePoint.SPException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. ---> System.Runtime.InteropServices.COMException (0x8102006D): The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation

Edit 2

Ok, I can break role inheritance fine without checking in/out. The reason I had all of that in there was because I am attempting to assign new permissions, which I think requires the update. I had stripped that out when posting. This is a records library, and items are immediately declared records. That's the need for the check in/out.

Edit 3

I ended up moving this to an event receiver. Worked as expected.

share|improve this question
    
I have played with this code in console application. Is there any special reason you are using check in/out? If you are only breaking permissions inheritance simple ´item.BreakRoleInheritance(false)´ will do. ´SystemUpdate()´ is also not needed. You also need to check if your file is not already checked out (it will throw exception if you call ´CheckOut()´ if file is already 'out'). Disclaimer: Since I am not too good at workflows and I tested this only in console app maybe I am not helping here :) –  Vedran Rasol Jan 10 '12 at 21:45
    
Can you try incorporating the SPUtility.ValidateFormDigest() or workflowProperties.Web.FormDigestSettings.Enabled = False in your code? –  Deepu Nair Jan 11 '12 at 8:38
    
See my edits... –  Tim Gabrhel Jan 11 '12 at 21:27
    
Deepu, FormDigestSettings are on the SPWebApplication, not SPWeb. I get an access denied trying that. –  Tim Gabrhel Jan 11 '12 at 22:05
    
I've had the same problem, workflow already assumes the RunWithElevatedPrivledges so don't set the AllowUnsafeUpdates back to false. –  Mike Mar 28 '13 at 13:43
add comment

4 Answers

up vote 2 down vote accepted

I would suggest running your code in ItemAdded event instead of an activity in a workflow. Also I don’t think BreakRoleInheritance requires you checkout the file, you may want to remove unwanted code.

share|improve this answer
    
This needs to be done in the workflow. See my update in the OP –  Tim Gabrhel Jan 11 '12 at 21:28
    
This is now an option. Exploring this idea as it seems a permission thing is better suited outside of the workflow –  Tim Gabrhel Jan 11 '12 at 22:11
add comment

If you have a need to update/modify a list item within a Workflow activity, you should only access that list item using the workflow item service, rather than accessing via the standard SharePoint SPList object.

I was reading all about this just the other day in the excellent Inside SharePoint 2010 book.

Pages 422 & 423 have the following to say about accessing tasks, site content and list items from custom code in a workflow activity context:

Note that the Execute method of an activity is always called by the WF runtime; it should never be called directly by developers. When the WF runtime calls the Execute method, it passes an ActivityExecutionContext parameter , which makes it possible to access workflow services. SharePoint Foundation extends WF with several SharePoint-specific workflow services, including the SharePoint Service, the Task Service, and the List Item Service, all of which can be accessed using the following code.

protected override ActivityExecutionStatus Execute(ActivityExecutionContext context) {  

  ISharePointService SPService =   
          (ISharePointService)context.GetService(typeof(ISharePointService)); 
  ITaskService TaskService =  
          (ITaskService)context.GetService(typeof(ITaskService)); 
  IListItemService ListItemService =  
          (IListItemService)context.GetService(typeof(IListItemService));  

  // Now perform work using workflow services 
}

Note that while your code is executing in the context of a workflow instance, you must create tasks and update site content using workflow services. For example, you should not create tasks and update list items using standard server-side object model techniques. Instead, you must create tasks using the Task Service and update items using the List Item Service. Here is a sample implementation of the Execute method that uses the SharePoint Service to log a comment to the workflow history list.

protected override ActivityExecutionStatus Execute(ActivityExecutionContext context) {  
  // get reference to SharePoint Service 
  ISharePointService SPService =   
          (ISharePointService)context.GetService(typeof(ISharePointService)); 

  // use SharePoint Service to perform work  
  SPService.LogToHistoryList( 
    this.WorkflowInstanceId,  
    SPWorkflowHistoryEventType.WorkflowComment, 
    this.UserId,  
    TimeSpan.MinValue, 
    "The 'Hello World' activity",  
    "My description",  
    "My custom data"); 

    // return Closed to indicate the activity has completed 
    return ActivityExecutionStatus.Closed; 
  }  
}
share|improve this answer
    
Thanks for the detailed and lengthy post, but I am not in a custom workflow activity. This is a visual studio custom workflow so I don't have a Context to work with. –  Tim Gabrhel Jan 11 '12 at 21:28
add comment

I've had the same problem, workflow already assumes the RunWithElevatedPrivledges so don't set the AllowUnsafeUpdates back to false.

share|improve this answer
add comment

You need to add a currentweb.allowunsafeupdate = true and currentsite.allenter code hereowunsafeupdates = true. Your error should go away.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.