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

What I am trying to do is to attach the OOTB sharepoint workflow [Approval Sharepoint - 2010] to each and every document library that ever gets created. To accomplish this I created a List Added event reciever and put this code in it -

public override void ListAdded(SPListEventProperties properties)
{
   SPSecurity.RunWithElevatedPrivileges(delegate()
   {  
       SPUtility.ValidateFormDigest();

        using (SPSite site = new SPSite(properties.SiteId))
        {
            using (SPWeb web = site.OpenWeb())
            {
                try
                {
                    base.ListAdded(properties);
                    if (currentList is SPDocumentLibrary)
                    {
                        SPDocumentLibrary docLib = (SPDocumentLibrary)properties.List;


                        //workflows need a tasks and history list. Here we assume they exist
                        SPList taskList = web.Lists["Tasks"];
                        SPList historyList = web.Lists["Workflow History"];

                        //loop through the workfows in the web and grab the one we want by name
                        SPWorkflowTemplate wfTemp = null;
                        foreach (SPWorkflowTemplate wt in web.WorkflowTemplates)
                        {
                            if (wt.Name == "Approval - SharePoint 2010")
                            {
                                wfTemp = wt;
                                Common.AddToLog(web, "Found " + wt.Name + " in current web " +
                                web.Url, false);
                                break;
                            }
                        }

                        //Now add the workflow to the doc library
                        SPWorkflowAssociation workFlow = SPWorkflowAssociation.CreateListAssociation(wfTemp, wfTemp.Name, taskList, historyList);

                        workFlow.AllowManual = true;
                        workFlow.AutoStartChange = false;
                        workFlow.AutoStartCreate = true;
                        workFlow.AssociationData = null;

                        web.AllowUnsafeUpdates = true;
                        web.ValidateFormDigest();
                        docLib.WorkflowAssociations.Add(workFlow);                                

                        docLib.EnableModeration = true;

                        docLib.Update();
                        web.Update();
                        web.AllowUnsafeUpdates = false;
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    web.AllowUnsafeUpdates = false;
                }
            }
        }
   });

}

I am getting this error-

The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.

at this line

docLib.WorkflowAssociations.Add(workFlow);

Any any have any suggestions please ? Thanks for your feedback.

share|improve this question
add comment

4 Answers

I believe updating this code block:

web.AllowUnsafeUpdates = true;
web.ValidateFormDigest();
docLib.WorkflowAssociations.Add(workFlow);

docLib.EnableModeration = true;

docLib.Update();
web.Update();
web.AllowUnsafeUpdates = false;

and replacing it with:

web.Site.WebApplication.FormDigestSettings.Enabled = false;
docLib.WorkflowAssociations.Add(workFlow);
docLib.EnableModeration = true;
docLib.Update();
web.Update();
web.Site.WebApplication.FormDigestSettings.Enabled = true;

Let me know if this works for you or if you still encounter the same error.

share|improve this answer
    
Did not work. Got Access Denied on web.Site.WebApplication.FormDigestSettings.Enabled = false; I tried with many various combinations but I could not get past the Access Denied error. Can you give some details of the situation where this formdigestsettings = false worked for you ? was it inside an event receiver ? –  vivek m Apr 23 '13 at 22:31
    
Logically, both ValidateFormDigest and AllowUnsafeUpdates don't belong in asynchronous EventReceivers, where there is no HttpContext involved and the code is definitely NOT processing a GET request. However, such errors do occur despite these belt-and-braces tricks. I'd really like to see a definitive answer here. –  Alexey Krasheninnikov Feb 6 at 7:18
add comment

Try to get all resources and objects that you need from the recently opened SPWeb and SPSite objects.

Avoid getting them from the receiver properties once you have your code running under elevated privileges, like on this line:

SPDocumentLibrary docLib = (SPDocumentLibrary)properties.List;

Try this instead:

SPDocumentLibrary docLib = (SPDocumentLibrary)web.Lists[properties.ListId];
share|improve this answer
add comment

Best practices in getting a reference while using List event receivers is to use something like

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPWeb web = properties.OpenWeb())
    {

      // web will be based on the rights for the system account
     // here follows your event handler code

    }

});

In your code you are getting a NEW reference to the SPSite which causes leaks. Also, make sure you do use EventFiringEnabled= false while performing changes.

share|improve this answer
    
Hi Marius, it is recommended to create a new SPSite object to utilize the RunWithElevatedPrivileges. Otherwise the code does not run as the app pool account. See this blog - firstblogofvarun.blogspot.com/2009/06/… –  vivek m Apr 23 '13 at 22:30
add comment

Looks like Vivek got his answer at StackOverflow: simply removing ValidateFormDigest did the trick for him.

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.