如何编写在相关子网格更新时触发的插件

时间:2018-07-31 15:33:28

标签: plugins dynamics-crm dynamics-365

我正在创建一个插件,该插件应该在合同实体表单上的子网格(合同细节)中添加新记录时触发。合同和合同细节(contract_line_items)之间存在1-N关系。我只希望在合同实体处于活动状态(状态代码== 0)时执行我的插件。.我只想基于此更新一些记录,但是,我无法根据我想要的条件来执行该插件。这是我到目前为止的内容:

using System;
using System.Collections.Generic;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;


/// <summary>
/// This plugin will update Unit Orders after the contract has already been invoiced.
/// The update will run on the alter unit orders.
/// </summary>

namespace MAGA.Plugins
{


    [CrmPluginRegistration(MessageNameEnum.Update,
    "contractdetail",
    StageEnum.PostOperation,
    ExecutionModeEnum.Asynchronous,
    "contractid",
    "Post-Invoice Contract",
    1000,
    IsolationModeEnum.Sandbox,
    Image1Name = "PreImage",
    Image1Type = ImageTypeEnum.PreImage,
    Image1Attributes = "")]
    public class UnitPluginPostInvoice : IPlugin
    {

        public void Execute(IServiceProvider serviceProvider)
        {
            // Extract the tracing service for use in debugging sandboxed plug-ins.
            // Will be registering this plugin, thus will need to add tracing service related code.

            ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

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

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

                Entity PreImage = context.PreEntityImages["PreIMage"];



                if (entity.LogicalName != "contractdetail" && entity.GetAttributeValue<OptionSetValue>("statecode").Value != 0)
                    return;


                IOrganizationServiceFactory serviceFactory =
                    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

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


                var contractId = entity.GetAttributeValue<EntityReference>("contractid");
                var contract = service.Retrieve(contractId.LogicalName, contractId.Id, new ColumnSet(true));

                if (contract.GetAttributeValue<OptionSetValue>("statecode").Value != 0)
                    return;

                try
                {
                    // Plugin code here
                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occured.. Phil is responsible. ", ex);
                }
                catch (Exception ex)
                {
                    tracing.Trace("An error occured: {0}", ex.ToString());
                    throw;
                }
            }


        }

    }

}

这是一张图片,仅供参考!

Contract Form

1 个答案:

答案 0 :(得分:1)

对代码的一些评论:

  • 插件是异步的。除非与Web服务进行通信,否则应切换为同步。它还可以为用户提供更好的反馈。
  • 该事件为Update(MessageNameEnum.Update),在这种情况下只能创建该事件
  • 获取合同状态时,请更改此:new ColumnSet(true)为此:new ColumnSet(“ statecode”)。 true表示返回所有列。
  • 将尝试捕获中的所有内容都包含在内。

其余的看起来不错。祝你好运,为我打招呼。