我正在为sharepoint工作流编写自定义活动,我不知道如何使用当前的工作流程项,SPWeb或SPSite。
我看到http://blogs.microsoft.co.il/blogs/davidbi/archive/2008/07/21/How-to-get-the-context-item-in-workflow-activity-sharepoint.aspx但是这个解决方案的xml例程对我来说太糟糕了。
也许还有另一个仅代码解决方案来获取Workflow活动中的上下文项?
答案 0 :(得分:19)
答案是几个步骤:
第1步:以下是属性的代码(我的类名为GetEmails,您需要将其重命名为您的类):
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);
}
}
第2步:然后在你的.actions文件中为你的块添加这些属性的映射(注意__ListID,__ListItem,__ Context和__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>
第3步: 这是一个示例执行函数:
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;
}
答案 1 :(得分:3)
我不确定这是否是2010 API中的更改,但__Context属性提供了所有必需的部分,包括列表和项目。以下示例包括@davek关于丢弃安全上下文的建议:
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);
答案 2 :(得分:2)
Kit Menke的答案非常全面,涵盖了您所需要的一切:我只会添加以下内容......
如果你这样做:
SPWeb tmpweb = __Context.Web;
SPSite site = new SPSite(tmpweb.Url);
SPWeb web = site.OpenWeb();
而不是:
SPWeb web = __Context.Web;
...
然后你就可以解除被触发它的人传递给工作流的安全上下文。
答案 3 :(得分:1)
查看SPWorkflowActivationProperties.Item Property
获取正在运行工作流实例的列表项。
答案 4 :(得分:1)
我尝试使用此代码并运行,但上下文对象始终为null。有人知道为什么吗?
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);
}
感谢
答案 5 :(得分:1)
我不知道这是否太容易了,但我用过:
objCurrentItem = workflowProperties.Item
获取工作流程中的项目(列表),然后更改列表中的项目