2

重新制定的问题(4 月 24 日):

我正在使用 VS2012 的 CRM 开发人员工具包来创建 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;
}

既然我们处于后期运算阶段,那么baseamountin的值postImageEntity应该已经从用户输入中计算出来了,对吧?但是,baseamountin 的postImageEntity值为零。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据我了解,发布实体图像是创建新发票详细信息后数据库中实体的快照。因此它应该包含新创建的发票明细的所有属性。

我得到了 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;

  }

添加:用于后期操作更新的前后图像包含基数的非零值。

4

3 回答 3

1

需要注意三件事,一件有望解决您的问题,另外两件是最佳实践。

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

    十进制 baseAmount = e.GetAttributeValue("baseamount").Value;

  3. 由于这是在创建发票详细信息时运行的,因此目标应包含创建期间填充的所有数据,这将消除对后期图像的需要。
于 2013-04-19T12:53:53.330 回答
0

只是为了关闭这个问题:最后,我在服务器上重新安装了 CRM 实例,问题就消失了。

于 2013-11-14T08:40:30.483 回答
0

您可以使用以下代码创建一个简单的插件.. 参考这里

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

        }
    }
于 2013-10-29T09:51:17.010 回答