0

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

截图:CRM注册工具

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

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

我一直在寻找一个星期的答案。我希望这里有人可以指导我解决这个问题。我可以提供您需要的所有代码或信息。但是现在,我想不出更多可能可以帮助您查看我的错误所在的位置。很感谢任何形式的帮助。

谢谢!

4

3 回答 3

4

如果插件注册为 pre 步骤,OutputParameters 将不包含键“id”,它会抛出该错误。

于 2011-05-31T15:02:29.960 回答
2

M.Medhat 是绝对正确的,但让我们进一步扩展它以便您理解。

您需要了解的第一件事是 InputParameters 与 OutputParameters 之间的区别。快速阅读这篇 MSDN 文章,描述 InputParameters 和 OutputParameters 之间的区别

请务必注意以下声明:

如果为前事件注册了插件,则 OutputParameters 属性包将不包含“id”键的值,因为尚未发生核心操作。

因此,此代码将中断:

var id = (Guid)context.OutputParameters["id"];

由于您已经创建了一个实体(通过将其从 InputParameters 中转换出来),您可以删除该行并执行以下操作:

AddNoteToContact(service, entity.id);

不要忘记追踪,它是你最好的朋友。它可以在抛出异常时显示信息。这是一个很好的链接:tracing

于 2011-05-31T16:52:07.677 回答
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))));
}
于 2012-06-23T00:47:46.500 回答