错误“在更新事件中创建新自定义实体时,字典中没有给定键”

时间:2015-10-15 21:20:19

标签: plugins crm dynamics-crm-2013

在CRM 2013 on-premise上,我正在尝试编写一个插件,当对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);

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

在上面的帖子中查看此行:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

首先,您没有说出抛出异常的行。放入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值不会为null,如果它通过了Contains测试,那么你真的不需要空检查。