刚开始做MOSS/WF工作流开发,很多地方还不熟悉,也没有系统的看过一些书籍,下面是在做的过程中遇到及思考的一些问题:
1.在多个地点部属工作流后,唯独有一个站点A的工作流无法启动,超时,N久后提示,由于内部错误工作流无法启动,这个问题困惑了我好久,终于发现A的siteusers有近2k多,而我在OnworkflowActivted中做了权限的配置,对于对当前相关工作流列表项有角色指定(roleassignment)的用户(继承过来的)断开权限,然后配置为读取权限,这样可防止在列表审批的过程中用户不能做数据的任何改动。
之前:
foreach (SPUser user in web.SiteUsers)
{
SPRoleAssignment ra = new SPRoleAssignment(web.EnsureUser(user.LoginName));
ra.RoleDefinitionBindings.Add(web.RoleDefinitions["读取"]));
item.RoleAssignments.Add(ra);
}
之后:
SPRoleAssignment ra = new SPRoleAssignment(web.EnsureUser(@"NT AUTHORITY\authenticated users"));
ra.RoleDefinitionBindings.Add(web.RoleDefinitions["读取"]);
item.RoleAssignments.Add(ra);
或者对组进行操作也可,不过效率还是这个最好。
2.item.BreakRoleInheritance(false)抛出异常,Exception from HRESULT: 0x80004004 (E_ABORT) 解决方法很多,google了一下大致有如下几种:
1)
Hi all,
![](/Images/OutliningIndicators/None.gif)
My MS support info for everyone.
Problem Description:
===============
When you call SPList.BreakRoleInheritance(false) from an HTTP GET request, although you have specified SPWeb.AllUnsafeUpdates=true, you will still be thrown an exception
![](/Images/OutliningIndicators/None.gif)
Updates are currently disallowed on GET requests. To allow updates on a GET, set the 'AllowUnsafeUpdates' property on SPWeb.
![](/Images/OutliningIndicators/None.gif)
Cause:
=====
This is by design limitation of SPList.BreakRoleInheritance
![](/Images/OutliningIndicators/None.gif)
BreakRoleInheritance does it work in two steps. First, it needs to revert its permission to have same permission settings as parent (this is a less expensive operation, and give the list a fresh start on its road to unique permission). Later it checks CopyRoleAssignments parameter. If it is false, it takes an extra step to clean up permission on the list. A side effect of step 1 is that it dirties some internal objects in SPWeb, and cause them to be recreated. Unfortunately, the re-creation of those internal objects cause SPWeb.AllowUnsafeUpdates to have a default value which is false. That is, SPWeb.AllowUnsafeUpdates is reset in middle of call to SPList.BreakRoleInheritance, therefore we got the exception.
![](/Images/OutliningIndicators/None.gif)
Resolution:
![](/Images/OutliningIndicators/None.gif)
========
![](/Images/OutliningIndicators/None.gif)
There are two possible workarounds to the issue:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
1. Call SPList.BreakRoleInheritance from a HTTP POST request. That is, we can first have a button on UI and have users to click. In response to users’ click, we call SPList.BreakRoleInheritance. There is a first HTTP GET request by which, SharePoint has a chance to embed some digest to validate requests on return (HTTP POST). Therefore, we no longer need to set SPWeb.AllowUnsafeUpdates=true. This is recommended approach from security perspective.
![](/Images/OutliningIndicators/None.gif)
2.First call SPList.BreakRoleInheritance(true). Then, use custom code to clean up permission and create your own permission set for the list as needed. The sample code are:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
SPWeb web = SPControl.GetContextWeb(this.Context);
![](/Images/OutliningIndicators/None.gif)
SPListCollection lists = web.Lists;
![](/Images/OutliningIndicators/None.gif)
//Guid docLibGuid = lists.Add("Doc Lib Sample 1", "Doc Lib Desc", SPListTemplateType.DocumentLibrary);
![](/Images/OutliningIndicators/None.gif)
//SPList docLib = lists[docLibGuid];
![](/Images/OutliningIndicators/None.gif)
SPList docLib = lists["Doc Lib Sample 1"];
![](/Images/OutliningIndicators/None.gif)
//docLib.ParentWeb.AllowUnsafeUpdates = true;
![](/Images/OutliningIndicators/None.gif)
docLib.BreakRoleInheritance(true); //Exception throw here when the parameters is "false"
![](/Images/OutliningIndicators/None.gif)
web.AllowUnsafeUpdates = true;
![](/Images/OutliningIndicators/None.gif)
SPRoleAssignmentCollection roleAssigns = docLib.RoleAssignments;
![](/Images/OutliningIndicators/None.gif)
for (int i = roleAssigns.Count-1; i >= 0; i--)
![](/Images/OutliningIndicators/None.gif)
{
roleAssigns.Remove(i);
}
![](/Images/OutliningIndicators/None.gif)
2)
SPWebApplication webApp = currentWeb.Site.WebApplication;
![](/Images/OutliningIndicators/None.gif)
bool formDigestEnabledStatus = webApp.FormDigestSettings.Enabled;
![](/Images/OutliningIndicators/None.gif)
webApp.FormDigestSettings.Enabled = false;
![](/Images/OutliningIndicators/None.gif)
//Do stuff to BreakRoleInheritance here
![](/Images/OutliningIndicators/None.gif)
webApp.FormDigestSettings.Enabled = formDigestEnabledStatus;
3.工作流调试问题,必须要卸载应用程序域里的所有dll引用(iisreset),在加载进程才ok,否则vs.net就会挂掉,仅在虚机上存在这个问题,这是为什么呢?
4.任务列表我看你不看的问题。详见:Item Level Permission in workflow CreateTaskXXX activities
5.在InfoPath表单内提交表单并启动工作流,这样就可以不用手动启动工作流,减少了好几步的额外操作。,以后准备改成使用infopath表单存数据而不是sharepoint列表时会用到这个在InfoPath表单内提交表单并启动工作流 ,至于数据在infopath里面如何统计,汇成报表的问题也还有待进一步研究。
6.既然是通用的审批工作流就要做到审批内容和审批流程的解耦,这里就存在一个问题,在用list存数据的时候,审批的过程中要查看送审信息就只能点以下列表的链接在另一个页面查看,然后再返回审批页面,用户体验不是很好(当然在审批信息很少且没有额外要求的情况下可设计在infopath表单里面)
7.workflow activity的使用。无论是标准的还是自己开发的,流程的可读性、代码的重用性和可维护性仍然是考虑的重点。
8.部署的问题,使用.wsp进行分发和更新。不过生产环境里debug的时候使用
cscript.exe c:\windows\system32\iisapp.vbs /a "SharePoint - 60" 替代iisreset以不影响现有系统的正常运行,却好像不起作用,也懒得去查vbs脚本了:(
1.在多个地点部属工作流后,唯独有一个站点A的工作流无法启动,超时,N久后提示,由于内部错误工作流无法启动,这个问题困惑了我好久,终于发现A的siteusers有近2k多,而我在OnworkflowActivted中做了权限的配置,对于对当前相关工作流列表项有角色指定(roleassignment)的用户(继承过来的)断开权限,然后配置为读取权限,这样可防止在列表审批的过程中用户不能做数据的任何改动。
之前:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2.item.BreakRoleInheritance(false)抛出异常,Exception from HRESULT: 0x80004004 (E_ABORT) 解决方法很多,google了一下大致有如下几种:
1)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
3.工作流调试问题,必须要卸载应用程序域里的所有dll引用(iisreset),在加载进程才ok,否则vs.net就会挂掉,仅在虚机上存在这个问题,这是为什么呢?
4.任务列表我看你不看的问题。详见:Item Level Permission in workflow CreateTaskXXX activities
5.在InfoPath表单内提交表单并启动工作流,这样就可以不用手动启动工作流,减少了好几步的额外操作。,以后准备改成使用infopath表单存数据而不是sharepoint列表时会用到这个在InfoPath表单内提交表单并启动工作流 ,至于数据在infopath里面如何统计,汇成报表的问题也还有待进一步研究。
6.既然是通用的审批工作流就要做到审批内容和审批流程的解耦,这里就存在一个问题,在用list存数据的时候,审批的过程中要查看送审信息就只能点以下列表的链接在另一个页面查看,然后再返回审批页面,用户体验不是很好(当然在审批信息很少且没有额外要求的情况下可设计在infopath表单里面)
7.workflow activity的使用。无论是标准的还是自己开发的,流程的可读性、代码的重用性和可维护性仍然是考虑的重点。
8.部署的问题,使用.wsp进行分发和更新。不过生产环境里debug的时候使用
cscript.exe c:\windows\system32\iisapp.vbs /a "SharePoint - 60" 替代iisreset以不影响现有系统的正常运行,却好像不起作用,也懒得去查vbs脚本了:(