SharePoint 2010重命名上载文档在资源管理器视图中失败

时间:2011-10-19 14:39:23

标签: sharepoint-2010

我正在尝试在SharePoint 2010中实现自定义,以便在将文档上载到库时,文件名将更改为在名称中包含文档ID。 (我知道人们不应该再担心文件名了,但我们已经列出了许多遗留文件和喜欢本地副本的用户。)

我能够在ItemAdded事件上实现自定义事件接收器,通过在文件名之前添加文档ID来重命名文件。这可以通过网络上传正确使用。

问题在于资源管理器视图。当我尝试在资源管理器视图中使用WebDAV添加文件时,我得到了该文件的两个副本。似乎当通过Web上传文件时,触发的事件是

  1. ItemAdding
  2. ItemAdded
  3. 但是当我将文件复制/粘贴到Explorer View时,我会看到以下事件:

    1. ItemAdding
    2. ItemAdded
    3. ItemAdding
    4. ItemAdded
    5. ItemUpdating
    6. ItemUpdated
    7. 结果是我有两个名称不同的文件(因为文档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);
      }
      

2 个答案:

答案 0 :(得分:3)

我发现使用Visual Studio工作流程可以让我最灵活地执行此操作。 SharePoint Designer工作流程会更简单,但更难部署到不同的站点和库。

在阅读了包括thisthis在内的一些好文章后,我提出了这个似乎有用的代码。它启动一个工作流并等待文档不在LockState中,然后处理文件名。

工作流程如下所示:

Workflow image

这是背后的代码:

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工作流程做任何事情 - 像这个例子中那样更改标题应该没问题。