用于CREATE的CRM 2011插件(后期操作):为什么后期实体图像和目标中的“baseamount”值为零?

时间:2013-04-19 12:18:17

标签: plugins dynamics-crm-2011 crm

重组问题(4月24日):

我正在使用CRM Developer Toolkit for VS2012来创建CRM2011插件。该插件已注册“发票产品”实体的CREATE消息。 Pipeline-Stage是后期操作,执行是同步的。我注册了一个包含baseamount的帖子图片。

该工具包创建一个如下所示的执行函数:

protected void ExecutePostInvoiceProductCreate(LocalPluginContext localContext)
{
    if (localContext == null)
    {
        throw new ArgumentNullException("localContext");
    }

    IPluginExecutionContext context = localContext.PluginExecutionContext;

    Entity postImageEntity = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null;
}

由于我们处于后期运营阶段,baseamountpostImageEntity的值应该已经从用户输入中计算出来了,对吧?但是,baseamountpostImageEntity的值为零。对于我使用以下代码获得的目标实体中baseamount的值也是如此:

Entity targetEntity = (context.InputParameters != null && context.InputParameters.Contains("Target")) ? (Entity)context.InputParameters["Target"] : null;

使用如下所示的检索请求,我得到baseamount的正确值:

Entity newlyCreated = service.Retrieve("invoicedetail", targetEntity.Id, new ColumnSet(true));
decimal baseAmount = newlyCreated.GetAttributeValue<Money>("baseamount").Value;

此问题未出现在更新事件的后期操作阶段。

我很高兴听到你的想法/解释/建议为什么会这样......

(更多信息:远程调试,无隔离模式,存储在数据库中的插件)

原始问题:

我正在研究CRM 2011的插件,该插件应该计算创建发票明细时要支付的税额。为此,我试图在后期运营阶段从后期实体图像中获取新创建的baseamount实体的invoicedetail。据我所知,post实体图像是创建新发票明细后数据库中实体的快照。因此,它应包含新创建的发票明细的所有属性。

我正在获取IPluginExecutionContext的“postentityimages”属性,该属性包含具有我注册的别名的实体(“postImage”)。这个“postImage”实体包含一个“baseamount”的键,但它的值为0.任何人都可以帮助我理解为什么会出现这种情况以及我能做些什么呢?

(我也注意到postImage不包含所有但只包含我注册的实体的子集。)

代码如下所示:

  protected void ExecutePostInvoiceProductCreate(LocalPluginContext localContext)
  {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

        // Get PluginExecutionContext to obtain PostEntityImages
        IPluginExecutionContext context = localContext.PluginExecutionContext;

        // This works: I get a postImage that is not null.
        Entity postImage = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null;

        // Here is the problem: There is a "baseamount" key in the postImage 
        // but its value is zero!
        decimal baseAmount = ((Money)postImage["baseamount"]).Value;

  }

附加:后期操作更新的前后图像包含baseamount的非零值。

3 个答案:

答案 0 :(得分:1)

有三点需要注意,一个有希望解决你的问题,另外两个是最佳实践。

  1. 帖子图片属性只会填充您在注册时指定要填充的值,因此请检查您是否已指定baseamount应包含在帖子图片中。 (如果用户没有该字段的权限,你也可能遇到安全问题,但由于它是0而不是null,我认为这不是问题)
  2. 使用GetAttributeValue,而不仅仅是访问实体的索引。如果字符串键不在实体属性集合中,则会抛出错误:

    decimal baseAmount = e.GetAttributeValue(“baseamount”)。Value;

  3. 由于这是在创建发票明细时运行的,因此目标应包含创建期间填充的所有数据,这将消除对后期图像的需求。

答案 1 :(得分:0)

您可以使用以下代码创建一个简单的插件。参考here

public void Execute(IServiceProvider serviceProvider)
    {
        // Obtain the execution context from the service provider.
        ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

        // Obtain the execution context from the service provider.
        IPluginExecutionContext context = (IPluginExecutionContext)
            serviceProvider.GetService(typeof(IPluginExecutionContext));

        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        // The InputParameters collection contains all the data passed in the message request.
        if (context.InputParameters.Contains("Target") &&
            context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];

            // Verify that the target entity represents an account.
            // If not, this plug-in was not registered correctly.
            if (entity.LogicalName != "account")
                return;

            try
            {

                     //Access / get data of entity
                     string country = entity.Attributes.ContainsKey("address1_county") ? entity.Attributes["address1_county"].ToString() : "";
                     //Update existing values in entity (Account)
                     entity.Attributes["name"] = "My Name"

            }

            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException(ex.Message + ", Stack trace : " +  ex.StackTrace);
            }

        }
    }

答案 2 :(得分:0)

刚刚结束这个问题:最后,我在服务器上重新安装了CRM实例,问题就消失了。