1. 关于Check-out 锁定的错误:
当针对表单库关联Workflow后,用InfoPath客户端打开表单填写表单,填写完直接用Save保存回表单库。按设置,一保存回去就自动触发了工作流。但是触发后,有时可以,有时却报了Occured Error的错误,工作流加载失败。
由于有存在成功的现象,因此怀疑哪里环境出了问题。后来在Central Administration v3中配置了记录Workflow Infrastructure的详细日志,才发现出现了说该表单被Check out,然后已经处于锁定状态,所以工作流无法启动的异常信息。
这是个非常奇怪的问题。一直无法找到真正问题根源,不知是否为Bug。最后只能绕过该问题,在表单最后放了一个提交按钮,自动提交后自动生成唯一文件名保存在SharePoint Form Library中,然后马上关闭表单即可。
2. 用SPD 2007设计Workflow的建议:
记得,开发人员不到万不得已不要用SharePoint Designer 2007来开发工作流。这种事情让业务人员(如果有这种业务人员)去干这活吧。毕竟我个人以为SharePoint Designer 2007应该是定位在业务人员使用上的。开发人员老实开发Activity让业务人员用SPD 2007去设计工作流,或者直接用VS2005开发设计工作流才是正确的做法。
SharePoint Designer 2007和Visual Studio2005两者用来设计工作流的初衷都是为了让技术人员尽量管技术,让业务人员尽量分析处理业务。对此,DSL是用于沟通IT人员和业务人员的一个不错的选择;但Visual Studio 2005下的设计工作流更适合于开发人员,只不过通过DSL来缩小了与业务人员之间的Gap。而SharePoint Designer 2007,经过我这段时间作为开发者的快乐并痛着的经历,我觉得它完全是为业务人员而定制的一个产品,而非开发人员。最有力的证据就是——对SPD 2007设计的工作流的部署!你在测试环境用了SPD 2007进行设计了工作流,那就别指望能完全正确的直接部署到正式环境中,最有效的做法就是完全用SPD 2007再在正式环境中实施一次,或者用了站点模板部署后起码你还得用SPD 2007再打开正式环境的Workflow“编译”一次。这是一个另人抓狂的动作。
3. 基于Silverlight的Web Workflow的想法:
以前,有一个想法,就是做一个基于WPF的MOSS Document Sync工具。用于本地文件夹与MOSS Document Library做同步的一个TrayIcon小软件,主要功能当时就做了几点:
- 任务栏界面
- 集成和管理AD身份
- 设置本地和MOSS文档库同步目录(可对应到文档库或文件夹)
- 支持私人文档库和共享文档库
- 支持单文件下载或多文件、文件夹打包下载
- 集成MOSS Search
后来很郁闷的我的移动硬盘丢了,该工具源代码连同很多积累多年的宝贝一起从人间蒸发了。装了Vista系统后就懒得再去重新整理这块代码,所以以前和人提起过这个咚咚,但后来友人跟我要去尝试时,一时糗大,只好用其他好处打发之 -_-|| 当时之所以开发这个工具,主要是得益于虚拟了一个磁盘来和远程FTP同步的一些工具软件的想法的激发,同时也是作为长期不在Office的人之间基于MOSS互相交流文档的一个补充。
现在WPF/E终于Release了版本Silverlight出来,正好以前接触过一个Web上拖拉设计Workflow的业务型应用,也看过http://www.netfxlive.com/之类的 Web工作流设计器,于是有个想法,想在Silverlight和Workflow Foundation上做一个偏向公文或普通文件流转业务的可拖拉的Web Workflow应用。目前还在构想中,有三四个技术点还在验证。因为个人编程属于爱好,所以兴致来了连夜写着就很快,没来或忙时就会显得拖拉点,所以这个应用在时间长度上会显得长点,一有任何进展会随时跟大家沟通,也欢迎有任何这方面兴趣或经验的人一起交流。
对WCF的了解还停留在2006年初看Indigo的地步。当时看了一本MS 2005年出版的《Programming Indigo》电子书,是一本非常棒的书,我只记得当时作为初学者我看第一遍的时候,对其中每个章节中的相关概念定义都能心领神会,这就说明这本书是一本非常棒、值得收藏的书。因为WCF的核心就是接口协议定义,而它做到了让初学者能迅速理解这些接口协议。
对于学习WCF,我个人理解是一定要理解WCF中的接口协议定义和规则约束!了解这些远远比你去看看Code,写写Sample来得重要许多。从某种意义上,学WCF就是学概念、学定义、学规则、学接口协议,而不是让你像学C#或ASP.NET那般追求深入实际应用,然后再去反过来体会C#/ASP.NET原理。
一晃,Indigo更名为WCF并入.net3.0概念中。天天念叨着WCF、WPF、WF,可是除了WF还顺应潮流接点轨外,WCF就停在Indigo阶段,WPF更仅仅只了解其相关的XAML知识。正好最近越忙越是精力充沛,抽空花了两三个小时翻了2007年2月刚出版的《Programming WCF Services》一书,算是在Indigo基础上重新认识了下WCF,感觉还OK,各类细节变来变去,但只要它的接口协议、概念定义没变就好办,剩下的就是从《Programming WCF Services》新书中挑几章自己兴趣的或感觉变化比较大的再细细品味下,也算完成本书的阅读工作了。
昨天我说花了一夜用HTML+Photoshop+Javascript搞了个系统原型,于是有人开始质疑我这个做法是否值得,理由是让美工或其他人搞个比自己搞既快又好。我承认自从99年接触Photoshop 3.0/4.0以来,我的美工水平一直停滞在满足图片的修修补补,让专业美工搞这个自然是快而好。但我想做一件事情,更多的应该是看做这件事情的目的。系统原型相当于建筑行业的图纸,其更多的价值在于迅速构建一个与用户沟通的管道,确保做出客户想要的东西,同时为后面的系统设计提供了基础约束。由于业务复杂,加上时间紧张,自己也弄过ps,就凑合了,最终效果也不错。
MS发布了个Windows Workflow Foundation Web Workflow Approvals Starter Kit,算是给了ASP.NET开发人员一个交待。
最近在做EPM,不过这个EPM没有用Project Server,却是完全用ASPNET + SQLServer搭建,这也是各种原因造就。不然利用 Project Server,一个小时应该可以搭建出一个简单却实用的 EPM 应用出来。恰巧上次和网友讨论过一些 MS 企业服务器产品的主要应用业务,这里也稍微整理下一些我接触过的MS服务器产品,不对的地方还请指正。
- Project Server: EPM
- SPS: Portal
- WSS: Team Work (Document Mgmt)
- BizTalk: EAI
- Commerce Server: EBusiness
- Content Management Server:WCM
- Exchange:Mail, Message platform
- LCS:IM
- MOSS:Portal+WCM+ECM+BI+Search+BPM
先看 Kaneboy 的《SharePoint Designer 2007, 强大的工作流设计器》。然后,我们针对利用 SPD 2007进行扩展、设计工作流三个常见问题做一些回答。由于开始步入大忙期,时间和精力有限,每个问题我都只点到为止,具体更细节就不累赘。
1、“从用户处收集数据”这个Action中输出的输出变量是什么,做什么用?或者换个问法,我怎么获取用户填写在收集表单里的数据?
A:输出的变量实际上是任务列表中的ItemID。“从用户处收集数据”这个Action是一个强迫工作流暂停以等待用户进行操作的过程。该Action实际是以任务形式在任务列表中新建一条任务向用户派发,然后用户上来编辑任务进行录入数据,以完成任务。这个输出变量ItemID就是用来定位获取用户填写的数据项的。在Conditions中放入“比较任意数据”,选择“任务”列表要查找用户输入值的哪个字段,然后下面把任务ID和输出变量关联即可。
2、初始变量Initiations和变量Variables有何区别?
A:初始变量赋值于工作流启动前,而Variables则赋值于工作流启动后。二者均在整个工作流生命周期内可用。初始变量工作流务必设置默认值,用于当新建就自动触发工作流的情景。无法通过查找获取到的数据,或者多次反复使用的数据都可以存入变量Variables中,以便在Workflow周期里方便使用。
3、自定义扩展Activity中,如何获取当前SPWeb、SPList、SPListItem、SPFile等?比如,最简单的,如何获取当前工作流运作的ListItem数据?
A:完全可以在自定义Activity中通过WorkflowContext上下文获取到当前项或当前SPWeb等信息。除非你要获取其他Site的数据,否则就没必要用去把Site Url、List Guid或ListItem ID等这些数据信息作为输入参数让工作流定制人员来手工输入以获取相关对象。
下面为一个代码模板(LiveWriter不支持代码色彩,就看黑白的代码吧):
public class MyActivity: Activity
{
#region Properties
public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(MyActivity));
[ValidationOption(ValidationOption.Required)]
public WorkflowContext __Context
{
get
{
return (WorkflowContext)base.GetValue(__ContextProperty);
}
set
{
base.SetValue(__ContextProperty, value);
}
}
public static DependencyProperty ListItemProperty = DependencyProperty.Register("ListItem", typeof(int), typeof(MyActivity));
[ValidationOption(ValidationOption.Required)]
public int ListItem
{
get
{
return (int)base.GetValue(ListItemProperty);
}
set
{
base.SetValue(ListItemProperty, value);
}
}
public static DependencyProperty ListIdProperty = DependencyProperty.Register("ListId", typeof(string), typeof(MyActivity));
[ValidationOption(ValidationOption.Required)]
public string ListId
{
get
{
return (string)base.GetValue(ListIdProperty);
}
set
{
base.SetValue(ListIdProperty, value);
}
}
#endregion
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Guid listGuid = Helper.GetListGuid(__Context, ListId);
SPList list = __Context.Web.Lists[listGuid];
SPListItem item = __Context.GetListItem(list, ListItem);
// 做自己的事 :)
return ActivityExecutionStatus.Closed;
}
其对应在 WSS.ACTIONS 中的节点配置如下: <Action Name="测试Activity"
ClassName="TestActivities.MyActivity"
Assembly="TestActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dd27a7cb343a4cac"
AppliesTo="list"
Category="我的自定义操作">
<RuleDesigner Sentence="输出 %1 到数据库">
<FieldBind Field="ListId,ListItem" Text="此列表" Id="1" DesignerType="ChooseDoclibItem" />
</RuleDesigner>
<Parameters>
<Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/>
<Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />
<Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" />
</Parameters>
</Action>
几点说明:
- AppliesTo="list" 表示应用到列表,还可以有 AppliesTo="all" 表示应用到包括列表在内的所有sharepoint库表。
- Category="我的自定义操作",就表示你在 SPD 2007中看到的 Actions 的分类。
- Action 内属性还有 ListModeration="true" 表示是否要显示未经审核的项,UsesCurrentItem="true" 表示直接使用当前项。
- DesignerType="ChooseDoclibItem" 表示点“此列表”后弹出选择对话框(ChooseDoclibItem限文档库,列表可用ChooseListItem),以选择参数 ListId 和 ListItem。DesignerType表示SPD 2007支持的各种类型,如整数Integer、字符串String,电子邮件Email(含Email关键参数,类似Field="To,CC,Subject,Body"),单个人员SinglePerson,多个人员Person,参数类型ParameterNames,待更新项类型UpdateListItem(类似Field="ListId,ListItem,ItemProperties"),还有一个我们第一个问题用的“向用户收集数据”用到的类型Survey。SPD 2007设计器都支持这些类型的直接设计,因为也才体现出其强大之处(当然也有不足,如不支持InfoPath,不支持调试,不支持StateMachine等)。
- Id="1" 表示对应 Sentence 中的 %1。比如上面效果,你在SPD 2007将看到显示为“输出 此列表 到数据库”,点此列表后,将弹出让你选择你要的项。
- 下面Parameters节点里就比较好理解了,只要注意 Direction 有 In 和 Out 作为输入参数和输出参数即可。
SPD 2007 设计工作流基本也就这些东西,主要要扩展的还是需要你用 VS2005 来自定义 Activity 配合,才能达到最大灵活性。
剩下的就是发挥想象力动手吧。