Philipp Schmid
Philipp Schmid

Reputation: 5828

SharePoint Workflow: how to update the item without triggering the workflow again

I have a SharePoint workflow which is running whenever the item changes. The workflow communicates with an external REST service. If the service returns a string, I want to update one of the field values with that string. Unfortunately, this update will trigger another instance of the workflow for this item once the current workflow terminates. I end up with an infinite loop!

How I can prevent this from happening? SPListItem has Update(), UpdateOverwriteVersion(), and SystemUpdate() methods but none of them seem to prevent subsequent workflows from being triggered.

I could inspect the last modified timestamp of the item and terminate the workflow if the last update happened within a certain timespan, but I am looking for a more robust solution.

Upvotes: 11

Views: 43105

Answers (5)

Dennis G
Dennis G

Reputation: 21788

Some more links because the above solution is not working for 2010:

The best solution:

Upvotes: 8

Adam Carr
Adam Carr

Reputation: 21

It seems Microsoft have reworked this in SharePoint 2010, the EventFiringEnabled and EventFiringDisabled have been made obsolete.

Instead use a boolean Property named EventFiringEnabled.

Upvotes: 2

Janis Veinbergs
Janis Veinbergs

Reputation: 6988

You could use some extension method to update item silently.

public static class SPListItemExtensions
{
/// <summary>
/// Provides ability to update list item without firing event receiver.
/// </summary>
/// <param name="item"></param>
/// <param name="doNotFireEvents">Disables firing event receiver while updating item.</param>
public static void Update(this SPListItem item, bool doNotFireEvents)
{
    SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling();
    if (doNotFireEvents)
    {
        try
        {
            rh.DisableEventFiring();
            item.Update();
        }
        finally
        {
            rh.EnableEventFiring();
        }
    }
    else
    {
        item.Update();
    }
}

/// <summary>
/// Provides ability to update list item without firing event receiver.
/// </summary>
/// <param name="item"></param>
/// <param name="incrementListItemVersion"></param>
/// <param name="doNotFireEvents">Disables firing event receiver while updating item.</param>
public static void SystemUpdate(this SPListItem item, bool incrementListItemVersion, bool doNotFireEvents)
{
    SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling();
    if (doNotFireEvents)
    {
        try
        {
            rh.DisableEventFiring();
            item.SystemUpdate(incrementListItemVersion);
        }
        finally
        {
            rh.EnableEventFiring();
        }
    }
    else
    {
        item.SystemUpdate(incrementListItemVersion);
    }
}

/// <summary>
/// Provides ability to update list item without firing event receiver.
/// </summary>
/// <param name="item"></param>
/// <param name="doNotFireEvents">Disables firing event receiver while updating item.</param>
public static void SystemUpdate(this SPListItem item, bool doNotFireEvents)
{
    SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling();
    if (doNotFireEvents)
    {
        try
        {
            rh.DisableEventFiring();
            item.SystemUpdate();
        }
        finally
        {
            rh.EnableEventFiring();
        }
    }
    else
    {
        item.SystemUpdate();
    }
}

private class SPItemEventReceiverHandling : SPItemEventReceiver
{
    public SPItemEventReceiverHandling() { }

    new public void DisableEventFiring()
    {
        base.DisableEventFiring();
    }

    new public void EnableEventFiring()
    {
        base.EnableEventFiring();
    }


   }
}

Upvotes: 18

Hojo
Hojo

Reputation: 935

you can use set field in current item instud of update list item.

Set field update the list item with out triggering new event

Upvotes: -3

UnhipGlint
UnhipGlint

Reputation: 339

Could you add a step to the beginning of the workflow that terminates the workflow if an update was triggered by a change to that field? (The one that is updated by using the service.)

You could have a hidden boolean field on the list item that you set to true when you update the list using the service. Then, at the beginning of the workflow, you could check to see if this field is set to true.

Upvotes: 0

Related Questions