首页 文章

CRM 2011 - 给定密钥不存在于字典中 - 更新联系人插件

提问于
浏览
0

我正在尝试将插件绑定到Microsoft Dynamics CRM 2011中的更新联系人事件 . 我已经创建了一个插件,我已经为我的组织注册了程序集和步骤 .

截图:CRM registration tool

目前,我正在为我的插件使用示例代码 .

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

我一直在寻找一周的答案 . 我希望这里有人可以指导我解决这个问题 . 我可以提供您需要的所有代码或信息 . 但就目前而言,我无法想到任何可以帮助您查看错误位置的内容 . 很感谢任何形式的帮助 .

谢谢!

3 回答

  • 1

    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);
    

    唐't forget about tracing, it'是你最好的朋友 . 它可以在抛出异常时显示信息 . 这是一个很好的链接:tracing

  • 4

    如果插件被注册为预先步骤,则OutputParameters将不包含键“id”,并且它将抛出该错误 .

  • 2

    下面是一些代码,用于帮助显示插件在为给定消息和目标实体注册时接收的所有参数,使用它来查找 are 存在的键 .

    如果你不太愿意通过文档来查看“应该”应该是什么,而不是只是试着看看实际发生了什么,只需将它放在你的插件中,注册你打算使用的步骤,它会告诉你究竟什么是params是为这一步提供的 .

    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))));
    }
    

相关问题