2010-03-17 83 views
11

我有一個SharePoint工作流程只要項目發生變化就會運行。該工作流程與外部REST服務進行通信。如果服務返回一個字符串,我想用該字符串更新字段值之一。不幸的是,一旦當前工作流程終止,此更新將觸發該項目的另一個工作流程實例。 我結束了一個無限循環!SharePoint工作流程:如何在不觸發工作流程的情況下更新項目

我該如何防止這種情況發生? SPListItem具有Update(),UpdateOverwriteVersion()和SystemUpdate()方法,但它們都不妨礙後續工作流的觸發。

我可以檢查項目的上次修改時間戳,並在上次更新發生在特定時間範圍內時終止工作流,但我正在尋找更強大的解決方案。

回答

17

你可以使用一些擴展方法來默默更新項目列表項。

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


    } 
} 
+0

這很好 - thx! – 2010-03-18 13:21:50

+1

建議:使用「using」模式實現SPItemEventReceiverHandling,請參閱http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/ – driAn 2010-05-07 08:35:23

+1

有關更多信息,請參閱下面的答案。適用於SP2010的示例和代碼 – 2011-06-28 17:04:59

0

如果更新是由對該字段的更改觸發的,那麼您是否可以向終止工作流程的工作流程的開始添加一個步驟? (通過使用該服務進行更新的那個)。

當您使用服務更新列表時,您可以在列表項上設置一個隱藏布爾字段,該列表項中設置爲true。然後,在工作流程開始時,您可以檢查該字段是否設置爲true。

+0

如何檢測哪個字段發生了變化?我沒有看到任何屬性表明這一點。 – 2010-03-17 23:50:37

+0

對不起,我應該澄清我的意思。我更新了我的答案。 – UnhipGlint 2010-03-17 23:51:07

+0

但是,我不必再次取消設置該隱藏的布爾型字段(這將再次觸發更新)? – 2010-03-17 23:59:58

-2

您可以使用設置字段在當前項目 instud 更新列表項目

集字段更新了新的觸發事件

+0

你能解釋一下你的意思嗎? – devi 2013-03-27 17:50:54

1

看來微軟在SharePoint 2010中重寫了這一點,EventFiringEnabled和EventFiringDisabled已經過時。

改爲使用名爲EventFiringEnabled的布爾型屬性。

相關問題