我正在尝试在SharePoint 2010中实现自定义,以便在将文档上载到库时,文件名将更改为在名称中包含文档ID。 (我知道人们不应该再担心文件名了,但我们已经列出了许多遗留文件和喜欢本地副本的用户。)
我能够在ItemAdded事件上实现自定义事件接收器,通过在文件名之前添加文档ID来重命名文件。这可以通过网络上传正确使用。
问题在于资源管理器视图。当我尝试在资源管理器视图中使用WebDAV添加文件时,我得到了该文件的两个副本。似乎当通过Web上传文件时,触发的事件是
但是当我将文件复制/粘贴到Explorer View时,我会看到以下事件:
结果是我有两个名称不同的文件(因为文档ID不同)。
我发现很多人在网上谈论这个问题(this是我发现的最好的文章)。有没有其他想法?在工作流程而不是事件接收器中执行此操作会更有意义吗?我可以使用预定作业,但如果文档名称在几分钟后发生更改,则可能会让用户感到困惑。
这是我的代码,在使用Web上传时效果很好,但在使用资源管理器视图时则不行:
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
SPListItem currentItem = properties.ListItem;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
EventFiringEnabled = false;
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
EventFiringEnabled = true;
}
}
}
catch (Exception ex)
{
//Probably should log an error here
}
base.ItemAdded(properties);
}
答案 0 :(得分:3)
我发现使用Visual Studio工作流程可以让我最灵活地执行此操作。 SharePoint Designer工作流程会更简单,但更难部署到不同的站点和库。
在阅读了包括this和this在内的一些好文章后,我提出了这个似乎有用的代码。它启动一个工作流并等待文档不在LockState中,然后处理文件名。
工作流程如下所示:
这是背后的代码:
namespace ControlledDocuments.RenameWorkflow
{
public sealed partial class RenameWorkflow : SequentialWorkflowActivity
{
public RenameWorkflow()
{
InitializeComponent();
}
public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
Boolean continueWaiting = true;
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void whileActivity(object sender, ConditionalEventArgs e)
{
e.Result = continueWaiting;
}
private void onWorkflowItemChanged(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void CheckFileStatus()
{
if (workflowProperties.Item.File.LockType == SPFile.SPLockType.None)
{
continueWaiting = false;
}
}
private void renameFile(object sender, EventArgs e)
{
try
{
SPListItem currentItem = workflowProperties.Item;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
}
}
}
catch (Exception ex)
{
//Should do something useful here
}
}
}
}
希望如果他们遇到同样的问题,这可以帮助其他人。
答案 1 :(得分:2)
好吧,我会选择工作流程解决方法...... imo有两个选项:
1)在文档库中创建一个布尔值,然后创建一个SPD工作流,该工作流在添加项目时触发,并将该字段设置为“已更改”或其他内容。在EventReceiver中,然后检查是否已设置该字段..
2)使用SPD工作流程做任何事情 - 像这个例子中那样更改标题应该没问题。