您听到的是正确的:ItemAdded 将在元数据完成之前触发,因为在文档库中,ItemAdded 在文档首次上传时触发,而不是在填写表单时触发。
我认为最流畅的选择是使用在文档库中创建项目时触发的工作流。如果你有的话,特别是使用 Visual Studio 2008 的基于代码的。可以在此处找到使用 Visual Studio 2008 制作工作流的一般演练:Wrangling SharePoint Workflows with Visual Studio。那篇文章实际上是我从一开始就学会制作工作流程的方法,所以我希望它对你有帮助,对我也有帮助。我会推荐这种方法而不是事件处理程序,因为您必须使用 ItemUpdated,这意味着您必须进行棘手的检查以确保它只运行一次。而我能想到的另一个选项,即制作自定义表单,不是很舒服必须一直这样做。
现在,制作您自己的工作流程。确保初始化工作流属性,如 onWorkflowActivated_Invoked 的链接中所示。如果您将表单中的所有必要字段都设为必填,这是一个非常简单的工作流程。在设计器视图中,除了 OnWorkflowActivated 活动之外,您只需要 2 个附加活动:一个 OnWorkflowItemChanged 活动和一个代码活动。对于 OnWorkflowItemChanged 活动,您需要设置的唯一属性是 CorrelationToken,它与 OnWorkflowActivated 活动的 CorrelationToken 相同。现在,双击 Code 活动以生成其 codeActivity_Executed 方法。在这种方法中,以下内容就足够了:
SPListItem item = workflowProperties.Item;
if (!item.File.Url.Contains("/NativeUrl/"))
{
string destination = item.ParentList.RootFolder.Name + "/NativeFile/" + item.File.Name;
item.File.CopyTo(destination, true);
}
我添加了 if 语句,因为工作流可能会在您使用 CopyTo 创建的新项目上触发,所以这将检查文件是否已经在文件夹中,如果是,它不会执行复制。现在,将工作流程与您的网站相关联,如链接中所示,并将其与项目创建相关联。那么它应该可以工作了。
即使此工作流在技术上等待 ItemUpdated,因为这是在填写字段时,通过将其与创建项目相关联,您可以确保它只运行一次。我承认我只使用了item.File.MoveTo(destination, true),但它确实保留了所有字段和元数据,所以我很确定 CopyTo 也应该如此。如果没有,请大声喊叫。