c# - Dynamics CRM插件 - 在创建之前自动填充数据

时间:2016-11-08 13:35:02

标签: javascript c# plugins dynamics-crm crm

我想使用插件来填充案例实体表单数据。我是新手使用c#和插件,但我觉得这比使用javascript表单脚本更可靠。如果这是一个不好的假设,请告诉我。

我的目标是1)获取并检查用户的安全角色,2)基于安全角色,使用通用的硬编码值自动填充“客户”字段。

案例表单上的“客户”字段是“需要系统”字段。我目前在Create of incident,pre-validation&同步。当我尝试保存而不手动填写“客户”字段时,我无法保存,并且UI指向我尚未填写该字段的事实。

我是否尝试做一些不可能的事情?或者我应该只是使用javascript和/或业务规则这样的事情?

4 个答案:

答案 0 :(得分:1)

  1. 插件很贵。根据您的需要,OnLoad JavaScript函数更合适。
  2. 关于预验证阶段,验证实际上是针对用户权限等内容进行检查;在客户端检查字段要求级别。因此,即使是预验证插件也无法帮助用户跳过必填字段。
  3. 如果您喜欢插件,则可以为此字段设置默认值,并在插件中填充正确的值。

答案 1 :(得分:1)

为了通过插件执行此操作,您可能需要对用户可能拥有的角色使用RetrieveMultiple请求,然后循环结果以根据角色分配客户字段值...

例如,如果您有一个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事件,并根据结果设置硬编码的所需值。< / p>

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 webresource实现 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;
}

答案 2 :(得分:1)

修改

Arun在评论中指出原始问题是关于Case(Create)实体,而该实体的Customer字段是无法修改为可选的必填字段

这意味着我的回答不适用于OP,但是我将它留在这里,以防它帮助任何在不同实体上工作的人

即使您已将插件设置为在预验证上执行,这仍然在InputParameters消息管道上,这意味着您必须先点击保存按钮。但是,您已将字段设置为必需字段,这就是您收到验证消息的原因

如果你想坚持这种方法,我会做出以下改变:

  1. 更改“客户”字段,使其不是强制性的
  2. 更改“客户”字段,使其为只读
  3. 根据您的描述(创建;预验证;同步)注册您的插件,根据您的业务需求(即基于用户的安全角色)更新事件的db.user.aggregate([ {"$sort": {"contactInfo.version": -1}}, {$group:{_id:"$contactInfo.contact", "maxValue": {$max:"$contactInfo.version"}, "userAgg": { "$first": "$$CURRENT" }}}, { $project : { "userAgg" : 1 ,_id : 0 }} ]);
  4. 此阶段的插件(预验证)意味着创建消息在到达CRM数据库并将更改注入数据之前将被截获。

    这样做的好处(使用插件代替其他用户建议的javascript)是它将应用于所有CRM表单

    这种方法的缺点是用户只能看到空客户字段,直到他们点击 save 。如果他们按保存并关闭,他们可能根本没有意识到客户已被设置。您可以通过将此字段移动到名为“自动完成”或“系统生成”的部分来解决此问题,以便用户知道这是自动填写的

答案 3 :(得分:0)

插件是更好的选择。在创建事件时设置虚拟客户,在预创建中,您可以识别实际客户&amp;覆盖虚拟值。

http://mobile.crmsoftwareblog.com/2016/09/service-case-customer-field-not-required-dynamics-crm-2016/