2010-03-17 16 views
11

Tengo un flujo de trabajo de SharePoint que es ejecutándose cada vez que el elemento cambia. El flujo de trabajo se comunica con un servicio REST externo. Si el servicio devuelve una cadena, quiero actualizar uno de los valores de campo con esa cadena. Lamentablemente, esta actualización activará otra instancia del flujo de trabajo para este elemento una vez que finalice el flujo de trabajo actual. ¡termino con un ciclo infinito!SharePoint Workflow: cómo actualizar el elemento sin activar nuevamente el flujo de trabajo

¿Cómo puedo evitar que esto suceda? SPListItem tiene los métodos Update(), UpdateOverwriteVersion() y SystemUpdate(), pero ninguno de ellos parece impedir que se desencadenen los siguientes flujos de trabajo.

Pude inspeccionar la última marca de tiempo modificada del artículo y finalizar el flujo de trabajo si la última actualización ocurrió dentro de un cierto intervalo de tiempo, pero estoy buscando una solución más robusta.

Respuesta

17

Usted podría utilizar algún método de extensión para actualizar el artículo silencio.

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

Esto funcionó bien, ¡gracias! –

+1

Una sugerencia: Implemente SPItemEventReceiverHandling utilizando el patrón "using", consulte http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/ – driAn

+1

Consulte las respuestas a continuación para obtener más información ejemplos y código que funciona para SP2010 –

0

¿Podría agregar un paso al principio del flujo de trabajo que finaliza el flujo de trabajo si se activó una actualización mediante un cambio en ese campo? (El que se actualiza al usar el servicio.)

Puede tener un campo booleano oculto en el elemento de lista que establece en verdadero cuando actualiza la lista usando el servicio. Luego, al comienzo del flujo de trabajo, puede verificar si este campo está establecido en verdadero.

+0

¿Cómo puedo detectar qué campo ha cambiado? No vi ninguna propiedad que indicara eso. –

+0

Lo siento, debería haber aclarado lo que quise decir. Actualicé mi respuesta. – UnhipGlint

+0

¿Pero no tengo que volver a desactivar ese campo booleano oculto (que activará la actualización nuevamente)? –

-2

puede utilizar campo de juego en el punto actual instud de actualización elemento de la lista.

campo Set actualización el elemento de lista con a desencadenar nuevo evento

+0

¿Puedes explicar a qué te refieres con el ejemplo? – devi

1

Parece Microsoft han vuelto a trabajar esto en SharePoint 2010, el EventFiringEnabled y EventFiringDisabled se han hecho obsoletas.

En su lugar use una propiedad booleana llamada EventFiringEnabled.

Cuestiones relacionadas