Friday, January 15, 2010

Error: Updates are currently disallowed on GET requests when you try to start a workflow programatically through code

Scenario:
While trying to start a workflow programatically through code, I had encountered the error "Updates are currently disallowed on GET requests".

My scenario was as below:
User fills in an infopath form and saves it, then closes it. Upon closing the form, I need to redirect users to an application page where a workflow is triggered, then redirect users to another page based on what the workflow does.

Explanation:
Even after ensuring that the 'AllowUnsafeUpdates' property on SPWeb was set to true, thie error kept showing up.

After a bit of reading, it was made clear to me that the workflows have to be started on a postback and that was the reason for the above error.

The below code can be used to raise a postback (assuming that there is a control on the page that can cause a postback such as a button with runat="server" set on it
if(!Page.IsPostBack)
{
  //If this is the first request, simulate button click to trigger the workflow
  String buttonClickSimulatorScript = "ButtonClickSimulatorScript";
  Type csType = this.GetType();
  ClientScriptManager cs = Page.ClientScript;

  // Check to see if the startup script is already registered.
  if (!cs.IsStartupScriptRegistered(csType, buttonClickSimulatorScript))
  {
    String js = "document.getElementById('"+[Control used to To Raise Postback].ClientID+"').click();";
    cs.RegisterStartupScript(csType, buttonClickSimulatorScript, js, true);
  }
}

and the code to start the workflow through code:

SPWeb web = [Do whatever to get to the web];
SPList list = [Do whatever to get the list];
SPListItem item = [Do whatever to get the item on which the workflow has to run];
SPWorkflowManager objWorkflowManager = SPContext.Current.Site.WorkflowManager;
SPWorkflowAssociationCollection objWorkflowAssociationCollection = list.WorkflowAssociations;
foreach (SPWorkflowAssociation objWorkflowAssociation in objWorkflowAssociationCollection)
{
    if (String.Compare(objWorkflowAssociation.BaseId.ToString("B"), [GUID of thw workflow], true) == 0)
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            web.AllowUnsafeUpdates = true;
            //Start the workflow...
            objWorkflowManager.StartWorkflow(item,
                                         objWorkflowAssociation,
                                         objWorkflowAssociation.AssociationData,
                                         true);

            web.AllowUnsafeUpdates = false;
        });
        break;
    }
}
The above code assumes that the list containing the item on which the workflow runs has the workflow attached to it already

No comments:

Post a Comment