Dynamics CRM插件-在创建之前自动填充数据
本文关键字:填充 数据 创建 CRM 插件 Dynamics | 更新日期: 2023-09-27 18:17:00
我想使用一个插件来填充案例实体表单数据。我刚开始使用c#和插件,但我觉得这比使用javascript表单脚本更可靠。如果这是一个错误的假设,请告诉我。
我的目标是1)获取并检查用户的安全角色,2)基于安全角色,用一个通用的硬编码值自动填充"Customer"字段。
案例表单上的"Customer"字段是"System Required"字段。我目前有一个插件注册创建事件,预验证&;同步的。当我尝试保存而不手动填写"Customer"字段时,我无法保存,并且UI向我指出该字段尚未填写的事实。
我正在尝试做一些不可能的事情吗?或者我应该使用javascript和/或业务规则这样的东西?
- 插件很贵。根据您的需要,OnLoad JavaScript函数更合适。
- 关于预验证阶段,验证实际上是针对诸如用户权限之类的事情进行检查;在客户端检查字段需求级别。因此,即使是预验证插件也无法帮助用户跳过必填字段。
- 如果插件是你的首选项,你可以为这个字段设置一个默认值,并在插件中填充正确的值。
为了通过插件做到这一点,你可能需要使用retrievmultiple请求用户可能拥有的角色,然后循环遍历结果,根据角色分配客户字段值…
例如,如果你有一个fetchxml来获得角色,你可以在你的插件中使用它(你可以使用QueryExpression,而不是fetchxml)…
string FetchXML =
@"<fetch mapping='logical' count='50' version='1.0'>
<entity name='systemuser'>
<attribute name='fullname' />
<link-entity name='systemuserroles' from='systemuserid' to='systemuserid'>
<link-entity name='role' from='roleid' to='roleid'>
<attribute name='name' />
</link-entity>
</link-entity>
</entity>
</fetch>";
EntityCollection result = svcClient.OrganizationServiceProxy.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(FetchXML));
// and then loop thru result
if (result != null)
{
foreach (var item in result.Entities) {
// ... do your stuff here
// item.roleName is just an idea.. I haven't tested the code yet..
Entity case = new Entity("case");
if (item.roleName == "role 01")
contact.Attributes["customer_field"] = "hard-code value 01";
if (item.roleName == "role 02")
contact.Attributes["customer_field"] = "hard-code value 02";
...
...
}
}
对于这个特殊的场景,我认为你可以通过使用javascript来实现它。如果你决定那样做,我有个主意…
将javascript函数(例如autoFillCustomer())附加到表单的onload事件,该事件将验证角色名称,并根据结果设置硬编码所需值。
function autoFillCustomer(){
var roles = getAllUserRolesNames();
var customerField = Xrm.Page.getAttribute("customer_field");
for (var i = 0; i < roles.length; i++) {
var roleName = roles[i];
switch (roleName) {
case "Role Name 01":
if ( customerField!= null )
customerFieldsetValue("hard-coded avlue 01");
break;
case "Role Name 021":
if ( customerField!= null )
customerFieldsetValue("hard-coded avlue 02");
break;
default;
if ( customerField!= null )
customerFieldsetValue("default value if needed");
}
}
}
然后. .另一方面,你可能有另一个js web资源的实现getAllUserRolesName(),并将其添加到您的表单。(这是因为您可以在未来的新场景中使用它)
// Display Name: Get All User Roles Names
// Description: Returns an array containing all the roles and teams currently assigned to a user
// This will contain the name and not the guid which is what the standard getUserRoles() function does.
function getAllUserRolesNames() {
var guid = "[A-z0-9]{8}-[A-z0-9]{4}-[A-z0-9]{4}-[A-z0-9]{4}-[A-z0-9]{12}";
var serverUrl = Xrm.Page.context.getClientUrl();
var userId = Xrm.Page.context.getUserId();
userId = userId.match(guid);
var teamQuery = "TeamMembershipSet?$select=TeamId&$filter=SystemUserId eq guid'" + userId + "'";
var teamRoleQuery = "TeamRolesSet?$select=RoleId&$filter=";
var roleQuery = "RoleSet?$select=Name&$filter=";
var teams = makeRequest(serverUrl, teamQuery, 0);
teamRoleQuery = composeQuery(teamRoleQuery, "TeamId", teams);
var teamRoles = makeRequest(serverUrl, teamRoleQuery, 1);
userRoles = Xrm.Page.context.getUserRoles();
if (userRoles != null) {
for (var i = 0; i < userRoles.length; i++) {
teamRoles.push(userRoles[i].match(guid));
}
}
roleQuery = composeQuery(roleQuery, "RoleId", teamRoles);
var roles = makeRequest(serverUrl, roleQuery, 2);
return roles;
}
function makeRequest(serverUrl, query, type) {
var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/";
oDataEndpointUrl += query;
var service = GetRequestObject();
if (service != null) {
service.open("GET", oDataEndpointUrl, false);
service.setRequestHeader("X-Requested-With", "XMLHttpRequest");
service.setRequestHeader("Accept", "application/json, text/javascript, */*");
service.send(null);
var retrieved = $.parseJSON(service.responseText).d;
var results = new Array();
switch (type) {
case 0:
for (var i = 0; i < retrieved.results.length; i++) {
results.push(retrieved.results[i].TeamId);
}
break;
case 1:
for (var i = 0; i < retrieved.results.length; i++) {
results.push(retrieved.results[i].RoleId);
}
break;
case 2:
for (var i = 0; i < retrieved.results.length; i++) {
if (results.indexOf(retrieved.results[i].Name) == -1) {
results.push(retrieved.results[i].Name);
}
}
break;
}
return results;
}
return null;
}
function GetRequestObject() {
if (window.XMLHttpRequest) {
return new window.XMLHttpRequest;
} else {
try {
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
} catch (ex) {
return null;
}
}
}
function composeQuery(queryBase, attribute, items) {
if (items != null) {
for (var i = 0; i < items.length; i++) {
if (i == 0) {
queryBase += attribute + " eq (guid'" + items[i] + "')";
} else {
queryBase += " or " + attribute + " eq (guid'" + items[i] + "')";
}
}
}
return queryBase;
}
EDIT
Arun在评论中指出,最初的问题是关于Case (incident
)实体的,该实体的Customer字段是必填字段,不能修改为可选的。
这意味着我下面的答案是不可能的OP,但我把它留在这里,以防它帮助任何人在不同的实体上工作
即使你已经将插件设置为在预验证时执行,这仍然是在Create
消息管道上,这意味着你必须先点击保存按钮。然而,你已经将字段设置为必需的这就是为什么你得到验证消息
如果您想坚持使用这种方法,我将做以下更改:
- 更改Customer字段,使其不再是强制性的
- 将Customer字段更改为只读
- 按照描述注册插件(创建;pre-validate;根据您的业务需求(即基于用户的安全角色)更新事件的
InputParameters
此阶段的插件(预验证)意味着创建消息将在它到达CRM数据库并将您的更改注入数据之前被拦截。
这样做的好处(使用插件而不是其他用户建议的javascript)是,它将应用于所有CRM表单
这种方法的缺点是用户只能看到空的customer字段,直到他们单击保存。如果他们按Save并关闭,那么他们可能根本没有意识到客户已被设置。您可以通过将该字段移动到名为"auto-completed"或"system-generated"的部分来解决这个问题,以便用户知道这是自动填写的Plugin是更好的选择。在创建事件时设置一个虚拟客户,在预创建中您可以识别实际客户&覆盖虚拟值
http://mobile.crmsoftwareblog.com/2016/09/service-case-customer-field-not-required-dynamics-crm-2016/