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

Plugins CRM 2011-字典中不存在给定密钥-更新联系人插件,plugins,crm,dynamics-crm-2011,Plugins,Crm,Dynamics Crm 2011,我正在尝试将插件绑定到Microsoft Dynamics CRM 2011中的更新联系人事件。 我已经做了一个插件,我已经为我的组织注册了程序集和步骤 截图: 现在,我正在为我的插件使用示例代码 public class Plugin : IPlugin { public void Execute(IServiceProvider serviceProvider) { IPluginExecutionContext context = (IPluginExecu

我正在尝试将插件绑定到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();
    }

}
}
我已经找了一个星期的答案了。我希望这里有人能指导我解决这个问题。我可以提供你需要的所有代码或信息。但就目前而言,我想不出还有什么能帮助您了解我的错误所在。非常感谢您的帮助


谢谢

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

M.med这是绝对正确的,但让我们对其进行进一步扩展,以便您理解

您需要知道的第一件事是InputParameters和OutputParameters之间的区别。快速阅读

请务必注意以下声明:

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

因此,此代码将破坏:

var id = (Guid)context.OutputParameters["id"];
由于您已经创建了一个实体(通过将其从InputParameters中去掉),您可以删除该行并执行如下操作:

AddNoteToContact(service, entity.id);

别忘了追踪,它是你最好的朋友。它可以在引发异常时显示信息。这里有一个很好的链接:

这里有一些代码,我用来帮助显示插件在为给定消息和目标实体注册时接收到的所有参数,使用它找出存在哪些键

如果您不太愿意通过文档来查看“应该”是什么,而只是尝试看看实际发生了什么,只需将其放入您的插件中,注册您打算使用的步骤,它就会准确地显示为该步骤提供了哪些参数

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))));
}
私有字符串参数选择器(KeyValuePair p、int索引、字符串inOut)
{  
返回String.Format(“{2}\tKey:'{0}'\tValue:{1}\n{3}”,p.Key,p.Value,inOut,EntityToTraceStrings(p.Value作为实体));
}
私有字符串EntityToTraceStrings(实体)
{
返回实体==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(“属性:{0}\t值:{1}”,p.Key,p.Value)));
}

你完全正确。但请记住,在此上下文中,
OutputParameters
中永远不会有id,因为
UpdateResponse
不包含此成员。将其与此成员有效的
Createresponse
进行比较。感谢您的帮助。回答这个问题后,我花了一段时间让我的插件工作,但那是因为这个插件中存在一些其他问题。按实体更改“id”。id=GREAT。你知道我如何从插件中获取app.config的值吗?因为我想那不包括在dll文件中。再次感谢!
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))));
}