SharePoint 2016 自定义操作触发工作流

SharePoint 2016 Custom Action to trigger a workflow

我正在尝试创建一个自定义操作,可以通过右键单击特定 SharePoint 库的任何文件夹中的文件来选择该操作。此自定义操作会将文件复制到同一文件夹中,并在文件名末尾附加用户的登录名。

我目前有一个事件接收器,它将在更新文件时执行自定义操作,但我不希望它发生。我能够使用 SharePoint Designer 将自定义操作添加到右键单击文件菜单,但 SharePoint Designer 只允许自定义操作触发特殊的 SharePoint 2010 兼容工作流或加载网页。我需要这样做,以便当用户在右键单击文件后选择自定义操作时触发事件处理程序(或可能是工作流)。我不确定我需要在 Visual Studio 2017 年创建哪种方法或哪种项目或应用程序才能获得此功能。

您的自定义操作应调用 javascript function 或对您的 SharePoint 托管 WCFASMX WebService 执行 GET request

  • ASMX

Official MSDN Walktrought: Creating a Custom ASP.NET Web Service

有关包含更多屏幕截图的其他资源,请查看 this blog post: Walkthrough: Creating a Custom ASP.NET (ASMX) Web Service in SharePoint 2010

  • WCF

Official Technet Walkthrough: SharePoint 2013: Create a Custom WCF REST Service Hosted in SharePoint and Deployed in a WSP

注意:使用GET request你将需要web.AllowUnsafeUpdate = true

使用 javascript 你需要 AJAX 调用即 jQuery.ajax()

/编辑

要连接 Web 服务和您的自定义操作,请使用 SharePoint Desinger,删除或更改您现有的自定义操作,将类型更改为 Navigate to URL 并在文本框中键入:

javascript: (function() { console.log('Testing...' + {ItemId}); /* your web service call */ })();

使用 {ItemId} 别名将正确的项目 ID 传递给您的 AJAX 调用。

另一方面,在 Web 服务端使用 SPWorkflowManager class 在项目上启动工作流。检查下面的代码 (link):

public void StartWorkflow(SPListItem listItem, SPSite spSite, string wfName)  {
    SPList parentList = listItem.ParentList;
    SPWorkflowAssociationCollection associationCollection = parentList.WorkflowAssociations;
    foreach (SPWorkflowAssociation association in associationCollection)  {
      if (association.Name == wfName){
       association.AutoStartChange = true;
       association.AutoStartCreate = false;
       association.AssociationData = string.Empty;
       spSite.WorkflowManager.StartWorkflow(listItem, association,  association.AssociationData);
       }
     }
}

我找到了一种使用 JavaScript 执行此操作的方法,无需 SharePoint Designer。我将以下脚本放在列表视图 Web 部件所在页面上的内容编辑器 Web 部件中,现在我可以右键单击一个文件并获得 "Get My Copy" 选项。如果您有 Comments 子文件夹,重命名的副本将放在那里。

<script type="text/javascript">

// adds the menu option to Get My Copy
function Custom_AddDocLibMenuItems(m, ctx)
{
    var strDisplayText = "Get My Copy";                  //Menu Item Text
    var strAction = "copyFile()"; 
    var strImagePath = "";                               //Menu item Image path
    CAMOpt(m, strDisplayText, strAction, strImagePath);  // Add our new menu item
    CAMSep(m);                                           // add a separator to the menu
    return false;                                        // false means standard menu items should also be rendered
}

// append current user account to filename and copy to subfolder named Comments 
function copyFile()
{
    // get web and current user from context
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    this.currentUser = web.get_currentUser();
    context.load(currentUser);

    // load the folder
    var currentFolder = decodeURIComponent(ctx.rootFolder);
    var folderSrc = web.getFolderByServerRelativeUrl(currentFolder); 
    context.load(folderSrc,'Files');

    context.executeQueryAsync(
        function() {            
            // get the first (and hopefully only) file in the folder
            var files = folderSrc.get_files();
            var e = files.getEnumerator();
            e.moveNext()    
            var file = e.get_current();

            // get user account
            var curUserAcct = currentUser.get_loginName();
            curUserAcct = curUserAcct.substring(curUserAcct.indexOf("\") + 1); 

            // get file without extension
            var file_with_ext = file.get_name();            
            var name_without_ext = file_with_ext.substr(0, file_with_ext.lastIndexOf("."));

            var destLibUrl = currentFolder + "/Comments/" + name_without_ext + " " + curUserAcct + ".docx";     
            file.copyTo(destLibUrl, true);

            context.executeQueryAsync(
                function() { alert("Success! File File successfully copied to: " + destLibUrl); }, 
                function(sender, args) { alert("error: " + args.get_message()) }
            );
        }, 
        function(sender, args){ alert("Something went wrong with getting current user or getting current folder '" + currentFolder + "'. " + args.get_message()); }
    );
}

</script>