在更新事件上创建新的自定义实体时出错"The given key was not present in the dictionary"



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

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

看看你上面的帖子:

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"];
}

在下面的代码段中,您正在检查属性"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);
        }

首先,不要说明是哪一行抛出了异常。输入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测试,你不需要null检查。

相关内容

最新更新