我正在尝试为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:给定的键不是 出现在字典中。
如果有人能帮助我,那就太棒了 - 非常感谢!
答案 0 :(得分:5)
为了解决问题,您需要了解分页列表字段的工作方式以及Activity Party entity对此的作用。
基本上,“from”字段(它也适用于电子邮件活动中的to,cc和cco字段)可以包含具有不同实体类型的多个实体引用。然后,Activity Party实体是一个“包装器”,允许您将所有这些不同的实体类型作为一个处理。您可以轻松地检查此检查 fromCollection 对象:
如果你更进一步检查那个实体的属性,你会发现属性不是你期望的属性,现在很明显错误是因为 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);
}