2010-03-17 4 views
11

J'ai un flux de travail SharePoint qui est s'exécutant chaque fois que l'élément change. Le flux de travail communique avec un service REST externe. Si le service renvoie une chaîne, je veux mettre à jour l'une des valeurs de champ avec cette chaîne. Malheureusement, cette mise à jour déclenchera une autre instance du flux de travail pour cet élément une fois que le flux de travail en cours se termine. Je me retrouve avec une boucle infinie!Flux de travail SharePoint: comment mettre à jour l'élément sans déclencher de nouveau le workflow

Comment puis-je empêcher cela? SPListItem possède les méthodes Update(), UpdateOverwriteVersion() et SystemUpdate(), mais aucune d'entre elles ne semble empêcher les flux de travail suivants d'être déclenchés.

Je pouvais inspecter le dernier horodatage modifié de l'élément et terminer le flux de travail si la dernière mise à jour avait eu lieu dans un certain laps de temps, mais je suis à la recherche d'une solution plus robuste.

Répondre

17

Vous pouvez utiliser une méthode d'extension pour mettre à jour l'article en silence.

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

Cela a bien fonctionné - merci! –

+1

Une suggestion: Implémentez SPItemEventReceiverHandling en utilisant le modèle "using", voir http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/ – driAn

+1

Voir les réponses ci-dessous pour plus d'informations exemples et code qui fonctionne pour SP2010 –

0

Pourriez-vous ajouter une étape au début du flux de travail qui met fin au flux de travail si une mise à jour a été déclenchée par une modification apportée à ce champ? (Celui qui est mis à jour en utilisant le service.)

Vous pouvez avoir un champ booléen caché sur l'élément de liste que vous définissez à true lorsque vous mettez à jour la liste en utilisant le service. Ensuite, au début du flux de travail, vous pouvez vérifier si ce champ est défini sur true.

+0

Comment puis-je détecter quel champ a changé? Je n'ai vu aucune propriété indiquant cela. –

+0

Désolé, j'aurais dû clarifier ce que je voulais dire. J'ai mis à jour ma réponse. – UnhipGlint

+0

Mais ne dois-je pas à nouveau désactiver ce champ booléen caché (ce qui déclenchera la mise à jour à nouveau)? –

-2

vous pouvez utiliser champ set au point courant instud de liste mise à jour point.

champ Set de mise à jour de l'élément de la liste sur le déclenchement nouvel événement

+0

pouvez-vous expliquer ce que vous voulez dire par exemple? – devi

1

Il semble Microsoft ont retravaillé cela dans SharePoint 2010, le EventFiringEnabled et EventFiringDisabled ont été rendus obsolètes. Au lieu de cela, utilisez une propriété booléenne nommée EventFiringEnabled au lieu de

Questions connexes