Dynamics CRM 2011-阻止通过插件创建实体

本文关键字:插件 创建 实体 CRM 2011- Dynamics | 更新日期: 2023-09-27 17:57:42

问题:我们使用CRM for Outlook插件自动记录我们的支持电子邮件,但员工之间的内部电子邮件(其中一些包含敏感信息)也被记录。

理想的解决方案:我正试图编写一个预事件("创建电子邮件"消息)插件来阻止内部电子邮件的自动记录,但(显然)阻止消息执行的唯一方法是在预事件阶段抛出异常,但这总是会导致outlook中显示错误消息(我们显然不能这样做)。根据文档,只有"InvalidPluginExecutionExeception"应该向用户显示消息,但事实并非如此,因为所有异常都会导致用户的Outlook应用程序中出现错误消息。

潜在解决方案:还有一条"CheckPromoteEmail"消息(根据文档)决定是否应将电子邮件升级到CRM(我认为"升级到CRM"的意思是"创建一个电子邮件实体存储在CRM中"),但我在上下文中找不到任何可以让我告诉CRM不要升级电子邮件的内容。是否有一些标志隐藏在我可以设置的上下文中,或者以某种方式询问电子邮件,以便CRM自己的逻辑决定不存储它?

变通解决方案:我所知道的(这里提到的)唯一的其他解决方案是在创建电子邮件后清除电子邮件的主题和内容,但我宁愿一开始就停止创建电子邮件,也不愿在创建电子邮件浪费时间和资源后编辑或删除它。

有没有一种干净的方法可以阻止插件的操作还是从任何地方?如果没有,有人知道微软为什么不提供这个功能吗?他们已经有了铁一般的回滚功能,以防操作失败,为什么不给我一种调用回滚的方法呢?

这是我的代码,以防它有助于回答我的问题:

public class InternalEmailFilter : IPlugin
{
    void IPlugin.Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        Entity e = (Entity)_context.InputParameters["Target"];
        bool shouldStore = ShouldStoreInCRM(e);
        if (shouldStore == false)
        {
            throw new Exception(); //attempting to stop the operation without an InvalidPluginExecutionException, but still results in error message to user
        }            
    }
    protected bool ShouldStoreInCRM(Entity e)
    {
           List<Entity> parties = new List<Entity>();
            var atttributes = e.Attributes;
            if (atttributes.ContainsKey("to") == true) parties.AddRange((atttributes["to"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("from") == true) parties.AddRange((atttributes["from"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("cc") == true) parties.AddRange((atttributes["cc"] as EntityCollection).Entities);
            if (atttributes.ContainsKey("bcc") == true) parties.AddRange((atttributes["bcc"] as EntityCollection).Entities);
            foreach (Entity p in parties)
            {
                if (p.LogicalName == "activityparty" && p.Attributes.ContainsKey("addressused") == true && p.Attributes["addressused"] != null)
                {
                    if (p.Attributes["addressused"].ToString().ToLower().Contains("@ourdomain.com") == false)
                    {
                        return true; //someone connected in the email is not an employee, store the email
                    }
                }
            }
            return false;  //everyone was an employee, do not store          
    }
}

Dynamics CRM 2011-阻止通过插件创建实体

在经历了大量的鲜血、汗水和泪水之后,我终于想出了如何做到这一点:

您必须在"创建电子邮件"消息上使用异步发布事件插件,才能在创建电子邮件后使用CRMService从数据库中删除该电子邮件它必须是异步的,因为您需要等待CRM完成创建并"释放"实体,然后才能删除它。否则,进程将挂起。

这些解决方案中的任何一个都会更好,但作为参考,您不能:

  1. 在预事件中引发异常以取消创建/提升电子邮件操作,而不会向用户显示错误消息或对其Outlook造成严重破坏。即使只有InvlaidPluginExectuionExection应该向用户显示消息,但所有异常都会向用户显示错误消息
  2. 阻止向CRM发送电子邮件的促销。CheckPromoteEmail邮件预事件(令人惊讶的是)没有提供关于可能要推广的邮件的信息(因此没有数据可以用来决定是否应该推广邮件),也没有什么可以用来告诉CRM不要推广邮件。而且,如果您使用pre/post事件,并尝试使用Output参数并在那里更改ShouldPromote标志,则它不会起任何作用
  3. 在为电子邮件创建实体之前,清除电子邮件的正文内容-您在预事件中对正文内容所做的任何更改都不会停留在执行上下文中,并且在核心操作开始时会丢失

疯狂。

对不起,解决方法是您唯一的选择。通过插件停止操作的唯一方法是抛出异常。微软为什么这么做?我想他们不希望插件默默地失败。

至于解决方法,您应该在主题和正文进入数据库之前,在事件前插件中清除它们,然后在事件后异步插件中清除记录本身。这样,敏感信息也不会进入任何审核日志。

最后,看看DeliverPromoteEmail而不是CreateEmailDeliverPromoteEmail是Outlook用来创建跟踪电子邮件的内容。这样你仍然可以在CRM UI中创建不启动此插件的电子邮件(如果需要)。

editCheckPromoteEmail只查看主题中的跟踪令牌(和/或电子邮件标头中的MessageID)来决定是否应该跟踪电子邮件,因此它也没有用处。

您可以在个人设置中选择跟踪所有电子邮件、对CRM电子邮件的电子邮件响应(已跟踪的电子邮件)、来自记录(帐户等)的电子邮件以及来自启用了电子邮件的记录的电子邮件。