SharePoint 2016 自定义操作触发工作流
SharePoint 2016 Custom Action to trigger a workflow
我正在尝试创建一个自定义操作,可以通过右键单击特定 SharePoint 库的任何文件夹中的文件来选择该操作。此自定义操作会将文件复制到同一文件夹中,并在文件名末尾附加用户的登录名。
我目前有一个事件接收器,它将在更新文件时执行自定义操作,但我不希望它发生。我能够使用 SharePoint Designer 将自定义操作添加到右键单击文件菜单,但 SharePoint Designer 只允许自定义操作触发特殊的 SharePoint 2010 兼容工作流或加载网页。我需要这样做,以便当用户在右键单击文件后选择自定义操作时触发事件处理程序(或可能是工作流)。我不确定我需要在 Visual Studio 2017 年创建哪种方法或哪种项目或应用程序才能获得此功能。
您的自定义操作应调用 javascript function
或对您的 SharePoint 托管 WCF
或 ASMX
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
注意:使用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>
我正在尝试创建一个自定义操作,可以通过右键单击特定 SharePoint 库的任何文件夹中的文件来选择该操作。此自定义操作会将文件复制到同一文件夹中,并在文件名末尾附加用户的登录名。
我目前有一个事件接收器,它将在更新文件时执行自定义操作,但我不希望它发生。我能够使用 SharePoint Designer 将自定义操作添加到右键单击文件菜单,但 SharePoint Designer 只允许自定义操作触发特殊的 SharePoint 2010 兼容工作流或加载网页。我需要这样做,以便当用户在右键单击文件后选择自定义操作时触发事件处理程序(或可能是工作流)。我不确定我需要在 Visual Studio 2017 年创建哪种方法或哪种项目或应用程序才能获得此功能。
您的自定义操作应调用 javascript function
或对您的 SharePoint 托管 WCF
或 ASMX
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
注意:使用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>