我正在尝试将插件绑定到Microsoft Dynamics CRM 2011中的更新联系人事件。 我已经制作了一个插件,我已经为我的组织注册了程序集和步骤。
目前,我正在为我的插件使用示例代码。
public class Plugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity entity;
// Check if the input parameters property bag contains a target
// of the create operation and that target is of type Entity.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target business entity from the input parameters.
entity = (Entity)context.InputParameters["Target"];
// Verify that the entity represents a contact.
if (entity.LogicalName != "contact") { return; }
}
else
{
return;
}
try
{
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(
typeof(IOrganizationServiceFactory));
IOrganizationService service =
serviceFactory.CreateOrganizationService(context.UserId);
var id = (Guid)context.OutputParameters["id"];
AddNoteToContact(service, id);
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException(
"An error occurred in the plug-in.", ex);
}
}
private static void AddNoteToContact(IOrganizationService service, Guid id)
{
using (var crm = new XrmServiceContext(service))
{
var contact = crm.ContactSet.Where(
c => c.ContactId == id).First();
Debug.Write(contact.FirstName);
var note = new Annotation
{
Subject = "Created with plugin",
NoteText = "This Note was created by the example plug-in",
ObjectId = contact.ToEntityReference(),
ObjectTypeCode = contact.LogicalName
};
crm.AddObject(note);
crm.SaveChanges();
}
}
}
但每次我修改联系表单并保存时,都会收到此错误:
The given key was not present in the dictionary
我一直在寻找一周的答案。我希望这里有人可以指导我解决这个问题。我可以提供您需要的所有代码或信息。但就目前而言,我无法想到任何可以帮助您查看错误位置的内容。非常感谢任何帮助。
谢谢!
答案 0 :(得分:4)
如果插件是作为预备步骤注册的,则OutputParameters将不包含键“id”,它将抛出该错误。
答案 1 :(得分:2)
M.Medhat绝对是正确的,但让我们进一步扩展它,让你明白。
您需要知道的第一件事是InputParameters vrs OutputParameters之间的区别。快速阅读this MSDN article describing the difference between InputParameters and OutputParameters。
请务必注意以下声明:
如果为事件注册了插件,则OutputParameters属性包将不包含“id”键的值,因为核心操作尚未发生。
因此,此代码会破坏:
var id = (Guid)context.OutputParameters["id"];
由于您已经创建了一个实体(通过将其从InputParameters中删除),您可以删除该行并执行以下操作:
AddNoteToContact(service, entity.id);
不要忘记追踪,这是你最好的朋友。它可以在抛出异常时显示信息。这是一个很好的链接:tracing
答案 2 :(得分:1)
以下是一些代码,用于帮助显示插件在为给定的消息和目标实体注册时收到的所有参数,使用它来找出哪些键 本。
如果你不太愿意通过文档来查看“应该”应该是什么,而不是试着看看实际发生了什么,只需将它放在你的插件中,注册你打算使用的步骤它会告诉你究竟为这一步提供了什么参数。
var propertiesList = String.Join("\n",
context.InputParameters.Select((p,i)=>ParamSelector(p,i,"Input")).Union(
context.InputParameters.Select((p,i)=>ParamSelector(p,i,"Output"))));
//send the list to the tracing service.
context.Trace("Listing Inputput and Output Parameters for the plugin.\n" + propertiesList);
// throw an exception to see the trace values pop-up (in a synchronous plugin).
throw new InvalidPluginExecutionException("Check the trace for a listing of parameters.");
支持代表进行格式化:
private string ParamSelector(KeyValuePair<string, object> p, int index, string inOut)
{
return String.Format("{2} \tKey:'{0}'\tValue:{1}\n{3}", p.Key, p.Value, inOut, EntityToTraceStrings(p.Value as Entity));
}
private string EntityToTraceStrings(Entity entity)
{
return entity == null ? String.Empty : String.Concat(
String.Format("- Entity: {0} Id: {1}\n\t", entity.LogicalName, entity.Id),
String.Join("\n\t", entity.FormattedValues.Select((p, j) => String.Format("Attribute: {0} \t Value: {1}", p.Key, p.Value))));
}