Microsoft Dynamics CRM - 电子邮件实体检索数据 - 插件

时间:2017-02-21 14:47:17

标签: c# plugins dynamics-crm dynamics-crm-online dynamics-crm-2016

我正在尝试为Microsoft Dynamics CRM Online中的电子邮件实体编写插件。让我们说它的名为" Sample_PlugIn"。

我希望插件检索电子邮件的发件人,并将他/她的电子邮件地址写入电子邮件的字段(new_samplefield)。

插件也做了一些其他的事情(并且它都在工作),但是代码的这一部分是制造问题的部分。 (我的组织服务引用称为"服务"。)

try                
{               
    Entity email = (Entity)context.InputParameters["Target"];

    EntityCollection fromCollection = (EntityCollection)email.Attributes["from"];

    if (fromCollection != null && fromCollection.Entities.Count > 0)
    {
        Entity sender = fromCollection[0]; 
        email["new_samplefield"] = (string)sender.Attributes["internalemailaddress"];
    }

    service.Update(email);
}

每次执行插件时,都会收到此错误:

  

插件出现意外异常(执行):   Sample_PlugIn.Sample_PlugIn:   System.Collections.Generic.KeyNotFoundException:给定的键不是   出现在字典中。

如果有人能帮助我,那就太棒了 - 非常感谢!

2 个答案:

答案 0 :(得分:5)

为了解决问题,您需要了解分页列表字段的工作方式以及Activity Party entity对此的作用。

基本上,“from”字段(它也适用于电子邮件活动中的to,cc和cco字段)可以包含具有不同实体类型的多个实体引用。然后,Activity Party实体是一个“包装器”,允许您将所有这些不同的实体类型作为一个处理。您可以轻松地检查此检查 fromCollection 对象:

enter image description here

如果你更进一步检查那个实体的属性,你会发现属性不是你期望的属性,现在很明显错误是因为 internalemailaddress 属性在此实体中不存在(实际上,此属性仅存在于systemuser实体中,因此您的插件未考虑帐户/联系人/等也可能是发件人)。

在partylist的属性中,您将找到两个有用的属性。 partyid 是被引用的记录(systemuser / contact / account / etc.)的实际EntityReference,因此您可以使用它来检索记录并获取必填字段。如果您只需要电子邮件地址,则可以使用 addressused 属性,如以下示例所示:

        Entity email = (Entity)context.InputParameters["Target"];

        EntityCollection fromCollection = (EntityCollection)email.Attributes["from"];

        if (fromCollection != null && fromCollection.Entities.Count > 0)
        {
            Entity sender = fromCollection[0];
            string emailAddress = (string)sender.Attributes["addressused"];
        }

答案 1 :(得分:2)

为了完整起见,这是最终对我有用的代码。在这种情况下,发件人是实体systemuser。 (我已在"操作后"以及"更新")上注册了此插件。)

try
{
    Entity email = (Entity)context.InputParameters["Target"];

    //  Post Entity Image (since the plug-in is registered on "Update")
    Entity postImage = context.PostEntityImages["Image"];

    EntityCollection fromCollection = postImage.GetAttributeValue<EntityCollection>("from");

    if (fromCollection != null && fromCollection.Entities.Count > 0)
    {
        Entity sender = fromCollection[0];
        EntityReference partyId = sender.GetAttributeValue<EntityReference>("partyid");

        string entityType = partyId.LogicalName.ToString();

        if (entityType == "systemuser")
            {
                //  Create query using querybyattribute
                QueryByAttribute queryToSender = new QueryByAttribute("systemuser");
                queryToSender.ColumnSet = new ColumnSet("systemuserid", "internalemailaddress");

                //  Attribute to query
                queryToSender.Attributes.AddRange("systemuserid");

                //  Value of queried attribute to return
                queryToSender.Values.AddRange(partyId.Id);

                EntityCollection retrievedFromSystemuser = service.RetrieveMultiple(queryToSender);

                foreach (Entity systemuserE in retrievedFromSystemuser.Entities)
                    {
                        email["new_samplefield"] = (string)systemuserE.Attributes["internalemailaddress"];                          
                    }
            }                     
        }

    service.Update(email);
}