2009-08-07 9 views
11

Sto scrivendo attività personalizzata per il flusso di lavoro di sharepoint e non so come utilizzare l'elemento del flusso di lavoro corrente, SPWeb o SPSite.Come ottenere l'elemento di contesto nell'attività del flusso di lavoro (SharePoint)

Vedo http://blogs.microsoft.co.il/blogs/davidbi/archive/2008/07/21/How-to-get-the-context-item-in-workflow-activity-sharepoint.aspx ma le routine xml di questa soluzione sono pessime per me.

Forse c'è un'altra soluzione di solo codice per ottenere l'elemento di contesto nell'attività del flusso di lavoro?

+0

Ho fatto tutto come descritto qui, eppure il mio contesto è sempre anche nullo. Sto codificando un'attività SPDesigner personalizzata basata su SequenceActivity. Inoltre, quando provo a modificare il WF in Sharepoint Designer, non posso salvarlo a causa di un errore. –

risposta

18

La risposta a questo è un paio di passi:

  1. aggiungere le proprietà per la vostra attività su misura cs
  2. link le proprietà nel file .actions (in modo SPD sa come mappa al tuo proprietà)
  3. utilizzare le proprietà nel codice

FASE 1: Ecco il codice per le proprietà (la mia classe si chiama GetEmails di cui avrete bisogno di rinominare per essere la classe):

public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(GetEmails)); 

[Description("The site context")] 
[Category("User")] 
[Browsable(true)] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
public WorkflowContext __Context 
{ 
    get 
    { 
     return ((WorkflowContext)(base.GetValue(GetEmails.__ContextProperty))); 
    } 
    set 
    { 
     base.SetValue(GetEmails.__ContextProperty, value); 
    } 
} 

public static DependencyProperty __ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ListId", typeof(string), typeof(GetEmails)); 

[ValidationOption(ValidationOption.Required)] 
public string __ListId 
{ 
    get 
    { 
     return ((string)(base.GetValue(GetEmails.__ListIdProperty))); 
    } 
    set 
    { 
     base.SetValue(GetEmails.__ListIdProperty, value); 
    } 
} 

public static DependencyProperty __ListItemProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ListItem", typeof(int), typeof(GetEmails)); 

[ValidationOption(ValidationOption.Required)] 
public int __ListItem 
{ 
    get 
    { 
     return ((int)(base.GetValue(GetEmails.__ListItemProperty))); 
    } 
    set 
    { 
     base.SetValue(GetEmails.__ListItemProperty, value); 
    } 
} 

public static DependencyProperty __ActivationPropertiesProperty = DependencyProperty.Register("__ActivationProperties", typeof(Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties), typeof(GetEmails)); 

[ValidationOption(ValidationOption.Required)] 
public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties __ActivationProperties 
{ 
    get 
    { 
     return (Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties)base.GetValue(GetEmails.__ActivationPropertiesProperty); 
    } 
    set 
    { 
     base.SetValue(GetEmails.__ActivationPropertiesProperty, value); 
    } 
} 

FASE 2: Poi, nel tuo .actions file di aggiungere al vostro blocco le mappature per quelle proprietà (notare il voci per __ListID, __ListItem, __Context e __ActivationProperties):

<Action Name="[DESCRIPTION OF YOUR ACTION]" 
    ClassName="[Your.Namespace.Goes.Here].GetEmails" 
    Assembly="[yourDLLName], Version=1.0.0.0, Culture=neutral, PublicKeyToken=0bfc6fa4c4aa913b" 
    AppliesTo="all" 
    Category="[Your Category Goes Here]"> 
    <RuleDesigner Sentence="[blah blah blah]"> 
    <FieldBind Field="PeopleFieldName" Text="people field" Id="1"/> 
    <FieldBind Field="Output" Text="emailAddress" Id="2" DesignerType="parameterNames" /> 
    </RuleDesigner> 
    <Parameters> 
    <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" /> 
    <Parameter Name="__ListId" Type="System.String, mscorlib" Direction="In" /> 
    <Parameter Name="__ListItem" Type="System.Int32, mscorlib" Direction="In" /> 
    <Parameter Name="PeopleFieldName" Type="System.String, mscorlib" Direction="In" /> 
    <Parameter Name="Output" Type="System.String, mscorlib" Direction="Out" /> 
    <Parameter Name="__ActivationProperties" Type="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties, Microsoft.SharePoint" Direction="Out" /> 
    </Parameters> 
</Action> 

FASE 3:

: Ecco un esempio funzione eseguono
+0

Grazie, questa soluzione mi ha aiutato. – avishnyakov

+0

Risposta eccellente e completa. Grazie! –

+0

Grazie! E quando abbiamo bisogno di ActivationProperties? – Serhiy

1

Date un'occhiata al SPWorkflowActivationProperties.Item Property

Ottiene l'elemento della lista su cui l'istanza del flusso di lavoro è in esecuzione.

+1

Hm .. Attuo la mia attività dalla classe base SequenceActivity. Dove posso trovare l'istanza SPWorkflowActivationProperties in questo caso? – avishnyakov

2

Kit risposta di Menke è molto completa e copre quasi tutto quello che ha bisogno di: vorrei solo aggiungere il seguente ...

Se si esegue questa operazione:

SPWeb tmpweb = __Context.Web; 
SPSite site = new SPSite(tmpweb.Url); 
SPWeb web = site.OpenWeb(); 

invece di questo:

SPWeb web = __Context.Web; 
... 

quindi sei libero dal contesto di sicurezza passato al flusso di lavoro dalla persona che lo ha attivato.

1

Provo questo codice e gira ugualmente bat il contex objet è sempre nullo. qualcuno sa perché?

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) 
    { 


     //return base.Execute(executionContext); 
     int IdRetorno = -1; 



     try { 
      SPSecurity.RunWithElevatedPrivileges(delegate 
      { 
       LogExceptionToWorkflowHistory("Inicio:", executionContext, WorkflowInstanceId); 
       using (SPSite sitio = new SPSite(this.__Context.Site.ID)) 
       { 

        using (SPWeb web = sitio.AllWebs[this.__Context.Site.ID]) 
        { 


         SPList sourceList = web.Lists[new Guid(ListId)]; 
         LogExceptionToWorkflowHistory(ListId, executionContext, WorkflowInstanceId); 
         SPList destinoList = web.Lists[new Guid(SourceListId)]; 
         LogExceptionToWorkflowHistory(SourceListId, executionContext, WorkflowInstanceId); 
         SPListItem sourceItem = sourceList.Items.GetItemById(ListItem); 
         LogExceptionToWorkflowHistory(ListItem.ToString(), executionContext, WorkflowInstanceId); 

         SPListItem destinoItem = destinoList.Items.Add(); 
         CopyFieldValues(sourceItem, destinoItem); 
         destinoItem.SystemUpdate(); 

         sourceItem.Delete(); 
         IdRetorno = destinoItem.ID; 
        } 
       } 

      }); 

     } 
     catch (Exception ex) { 
      if (!System.Diagnostics.EventLog.SourceExists("MyApp1")) 
       System.Diagnostics.EventLog.CreateEventSource(
        "MyApp1", "Application"); 

      EventLog EventLog1 = new EventLog(); 
      EventLog1.Source = "MyApp1"; 
      EventLog1.WriteEntry(ex.Message,EventLogEntryType.FailureAudit); 

      LogExceptionToWorkflowHistory(ex.Message, executionContext, WorkflowInstanceId); 
     } 


     OutListItemID = IdRetorno; 




     return base.Execute(executionContext); 

    } 

grazie

+0

La mia ipotesi è perché è racchiusa all'interno di RunWithElevatedPrivileges bloccare. Penso che dovresti passare l'id del sito in qualche altro modo? –

1

Non so se questo è troppo facile, ma ho usato:

objCurrentItem = workflowProperties.Item 

per ottenere l'oggetto all'interno del flusso di lavoro (una lista) e poi per alterare gli articoli nell'elenco

3

Non sono sicuro che questa sia una modifica nell'API 2010 ma la proprietà __Context fornisce tutti i pezzi necessari, inclusi l'elenco e l'elemento. L'esempio qui sotto include il suggerimento di @ davek per scartare il contesto di sicurezza:

  var contextWeb = __Context.Web; 
      var site = new SPSite(contextWeb.Url); 
      var web = site.OpenWeb(); 

      var list = web.Lists[new Guid(__Context.ListId)]; 
      var item = list.GetItemById(__Context.ItemId); 
Problemi correlati