【问题标题】:Error "The given key was not present in the dictionary" When Creating New Custom Entity on Update Event在更新事件上创建新的自定义实体时出现错误“字典中不存在给定的键”
【发布时间】:2015-10-15 21:20:18
【问题描述】:

在内部部署的 CRM 2013 上,我正在尝试编写一个插件,该插件会在对 Quote 上的字段进行更新时触发。然后插件创建一个新的自定义实体“new_contract”。

当对该字段进行更新时,我的插件被成功触发。但是,在尝试创建新的自定义实体时,我不断收到错误消息“字典中不存在给定的键”。

我在这段代码中使用了“PostImage”。我确认它在插件注册中使用相同的名称注册。

这里是代码

var targetEntity = context.GetParameterCollection<Entity>
                   (context.InputParameters, "Target");
if (targetEntity == null)
  {throw new InvalidPluginExecutionException(OperationStatus.Failed, 
            "Target Entity cannot be null")}
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
  {throw new InvalidPluginExecutionException(OperationStatus.Failed, 
            "Post Image is required");}

var quote = context.GenerateCompositeEntity(targetEntity, postImage);
//throw new InvalidPluginExecutionException(OperationStatus.Failed, "Update is captured");
//Guid QuoteId = (Guid)quote.Attributes["quoteid"];
var serviceFactory = (IOrganizationServiceFactory)serviceProvider
                       .GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);

var contractEntity = new Entity();
contractEntity = new Entity("new_contract");
if (quote.Attributes.Contains("portfolio"))
{
  var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
  contractEntity[Schema.new_contract.PortfolioName] = 
       new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
if (quote.Attributes.Contains(Schema.Quote.QuoteName))
{
  var quoteName = (string)quote.Attributes["name"];
  contractEntity[Schema.new_contract.contractName] = quoteName;
}
var contractId = service.Create(contractEntity);

【问题讨论】:

  • 显示您的完整方法。您在声明中使用var,因此您发布的内容中每种类型都不清楚。

标签: plugins crm dynamics-crm-2013


【解决方案1】:

我认为上下文不包含“PostImage”属性。您应该在获取数据之前检查上下文以查看它是否包含该属性。

【讨论】:

  • 但是我已经添加了在 postImage == null 时抛出新的 InvalidPluginExecutionException。它应该抛出这个错误,但在我的情况下它没有。
  • 如果 context 只包含一条记录,您可以尝试 context[0].Attributes.Contains("PostImage")。如果上下文具有 PostImage 属性,您可以填充“postImage”对象。
【解决方案2】:

看看你上面帖子中的这一行:

var service = serviceFactory.CreateOrganizationService(context.UserId);

我推断您的context 变量的类型是LocalPluginContext(因为它包含UserId 值),它不会公开图像(如另一个答案所述)。

要访问图像,您需要进入插件执行上下文

IPluginExecutionContext pluginContext = context.PluginExecutionContext;

Entity postImage = null;
if (pluginContext.PostEntityImages != null && pluginContext.PostEntityImages.Contains("PostImage))
{
    postImage = pluginContext.PostEntityImages["PostImage"];
}

【讨论】:

  • 感谢您的建议不幸的是这部分不起作用 IPluginExecutionContext pluginContext = context.PluginExecutionContext;
【解决方案3】:

在下面的代码段中,您正在检查属性“portfolio”并使用“new_portfolio”。你能纠正一下,让我们知道这是否有效。

if (quote.Attributes.Contains("portfolio"))
        {
            var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
            contractEntity[Schema.new_contract.PortfolioName] = new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
        }

【讨论】:

  • 我的复制粘贴不好;两者都应该是“new_portfolio”。不过感谢您的注意。
【解决方案4】:

首先,您不要说是哪一行引发了异常。放入VS调试器,找到抛出异常的那一行。

我确实看到您在这里尝试从字典中读取而没有首先检查字典是否包含键,这可能是此异常的来源。

var postImage = context.PostEntityImages["PostImage"];

if (postImage == null) 
    throw new InvalidPluginExecutionException(OperationStatus.Failed, 
    "Post Image is required");

试试这个:

if(!context.PostEntityImages.Contains("PostImage") ||
   context.PostEntityImages["PostImage"] == null)
   InvalidPluginExecutionException(OperationStatus.Failed, "Post Image is required");

var postImage = context.PostEntityImages["PostImage"];

虽然,我认为 PostEntityImage 值永远不会为空,但如果它通过了 Contains 测试,那么您实际上并不需要空值检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多