2009-08-07 4 views
11

Ich schreibe eine benutzerdefinierte Aktivität für den SharePoint-Workflow und ich weiß nicht, wie ich den aktuellen Workflow-Artikel, SPWeb oder SPSite verwenden kann.So rufen Sie das Kontextelement in der Workflow-Aktivität (SharePoint) ab

Ich sehe http://blogs.microsoft.co.il/blogs/davidbi/archive/2008/07/21/How-to-get-the-context-item-in-workflow-activity-sharepoint.aspx aber Xml Routinen dieser Lösung ist zu schlecht für mich.

Vielleicht gibt es eine andere Code-only-Lösung, um Kontextelement in Workflow-Aktivität zu erhalten?

+0

Ich habe alles wie hier beschrieben, und dennoch ist mein Kontext immer null. Ich programmiere eine benutzerdefinierte SPDesigner-Aktivität basierend auf SequenceActivity. Mehr noch, wenn ich versuche, die WF in Sharepoint Designer zu bearbeiten, kann ich sie wegen eines Fehlers nicht speichern. –

Antwort

18

Die Antwort darauf ist ein paar Schritte:

  1. die Eigenschaften in Ihrer .actions Datei
  2. Link-CS- die Eigenschaften Ihrer benutzerdefinierten Aktivität hinzufügen (so SPD weiß, wie man Ihre zur Karte Eigenschaften)
  3. Verwenden Sie die Eigenschaften in Ihrem Code

SCHRITT 1: Hier ist der Code für die Eigenschaften (meine Klasse GetEmails benannt, die Sie benötigen, um benennen Sie Ihre Klasse sein):

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

SCHRITT 2: Dann in Ihrer .actions Datei auf Ihrem Block die Zuordnungen für diese Eigenschaften (beachten Sie die hinzufügen Einträge für __ListID, __ListItem, __Context und __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> 

SCHRITT 3: Hier wird ein Beispiel Funktion ausführen:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext provider) 
{ 
    Output = string.Empty; 

    try 
    { 
     SPWeb web = __Context.Web; 
     // get all of the information we currently have about the item 
     // that this workflow is running on 
     Guid listGuid = new Guid(__ListId); 
     SPList myList = web.Lists[listGuid]; 
     SPListItem myItem = myList.GetItemById(__ListItem); 

     //... 
    } 
    catch (Exception e) 
    { 
     //... 
    } 

    return ActivityExecutionStatus.Closed; 
} 
+0

Danke, diese Lösung hat mir geholfen. – avishnyakov

+0

Ausgezeichnete und gründliche Antwort. Vielen Dank! –

+0

Danke! Und wann benötigen wir ActivationProperties? – Serhiy

1

Werfen Sie einen Blick auf den SPWorkflowActivationProperties.Item Property

Ruft das Listenelement, auf das die Workflow-Instanz läuft.

+1

Hm .. Ich implementiere meine eigene Aktivität von SequenceActivity Basisklasse. Wo finde ich in diesem Fall die Instanz von SPWorkflowActivationProperties? – avishnyakov

2

Kit Antwort Menke ist sehr umfangreich und deckt so gut wie alles, was Sie brauchen: Ich würde die folgende ... nur hinzufügen

Wenn Sie dies tun:

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

statt dessen:

SPWeb web = __Context.Web; 
... 

dann sind Sie frei von dem Sicherheitskontext, der von der Person, die sie ausgelöst hat, an den Workflow übergeben wurde.

1

Ich versuche diesen Code und läuft auch Bat das contex objet ist immer null. jemand weiß warum?

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

    } 

dank

+0

Meine Vermutung ist, dass es in RunWithElevatedPrivileges eingeschlossen ist Block. Ich denke, Sie müssten die Website-ID auf andere Weise weitergeben? –

1

Ich weiß nicht, ob dies zu einfach ist, aber ich verwende:

objCurrentItem = workflowProperties.Item 

das Element innerhalb des Workflows (eine Liste) und dann zu bekommen zu ändern Die Elemente in der Liste

3

Ich bin mir nicht sicher, ob dies eine Änderung in der API 2010 ist, aber die Eigenschaft __Context bietet alle erforderlichen Teile, einschließlich der Liste und des Elements. Das folgende Beispiel enthält den Vorschlag von @davek, den Sicherheitskontext zu verwerfen:

  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); 
Verwandte Themen