繁体   English   中英

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

[英]Dynamics CRM 2011 - Block Creation of Entity via Plugin

问题:我们使用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          
    }
}

经过大量的血,汗和泪,我终于想出了如何做到这一点:

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

任何这些解决方案都会更好,但作为参考,你不能:

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

郁闷了。

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

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

最后,查看DeliverPromoteEmail而不是CreateEmail DeliverPromoteEmail是Outlook用于创建跟踪的电子邮件的内容。 这样,您仍然可以在CRM UI中创建不会触发此插件的电子邮件(如果需要)。

编辑 CheckPromoteEmail仅查看主题中的跟踪令牌(和/或电子邮件标题中的MessageID)以确定是否应跟踪电子邮件,因此它也没有用处。

您可以选择在个人设置中选择跟踪所有电子邮件,电子邮件回复CRM电子邮件(已经跟踪的电子邮件),来自记录(帐户等)的电子邮件以及已启用电子邮件的记录中的电子邮件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM