web-dev-qa-db-ja.com

SharePointワークフロー:ワークフローを再度トリガーせずにアイテムを更新する方法

SharePointワークフローがありますアイテムが変更されるたびに実行されます。ワークフローは外部のRESTサービスと通信します。サービスが文字列を返す場合、その文字列でフィールド値の1つを更新にします。残念ながら、この更新は現在のワークフローが終了したら、このアイテムのワークフローの別のインスタンスをトリガーします。無限ループになります!

これを防ぐにはどうすればよいですか? SPListItemにはUpdate()、UpdateOverwriteVersion()、およびSystemUpdate()メソッドがありますが、後続のワークフローのトリガーを妨げるものはないようです。

アイテムの最後に変更されたタイムスタンプを調べて、最後の更新が特定の期間内に発生した場合はワークフローを終了できますが、より堅牢なソリューションを探しています。

11
Philipp Schmid

いくつかの拡張メソッドを使用して、アイテムをサイレントに更新できます。

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();
    }


   }
}
18
Janis Veinbergs

上記のソリューションは2010年には機能しないため、さらにいくつかのリンクがあります。

最良の解決策:

8
Dennis G

MicrosoftはSharePoint2010でこれを作り直したようで、EventFiringEnabledとEventFiringDisabledは廃止されました。

代わりに、EventFiringEnabledという名前のブールプロパティを使用してください。

2
Adam Carr

そのフィールドへの変更によって更新がトリガーされた場合にワークフローを終了するステップをワークフローの先頭に追加できますか? (サービスを利用して更新されたもの。)

サービスを使用してリストを更新するときにtrueに設定したリスト項目に、非表示のブール値フィールドを含めることができます。次に、ワークフローの開始時に、このフィールドがtrueに設定されているかどうかを確認できます。

0
UnhipGlint