plugins - 如何编写一个在相关子网格更新时触发的插件
问题描述
我正在创建一个插件,该插件应该在合同实体的表单上的子网格(contractdetail)中添加新记录时触发。contract 和 contractdetail (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;
}
}
}
}
}
这是一张供视觉参考的图片!
解决方案
对代码的一些评论:
- 该插件是异步的。除非您正在与 Web 服务通信,否则您应该切换到同步。它还为用户提供了更好的反馈。
- 事件是更新(MessageNameEnum.Update),它应该只在这种情况下创建
- 当您获取合约状态时,更改此:new ColumnSet(true) 为:new ColumnSet("statecode")。true 表示返回所有列。
- 在 try-catch 中包含所有内容。
其余的看起来不错。祝你好运,替我向菲尔问好。
推荐阅读
- weblogic - Jrebel 不适用于 weblogic 12.X
- javascript - 节点上的文件创建问题
- ios - 如何在后面的代码中设置常量属性以使用 xamarin IOS 查看
- php - if 子句不给更新只适用于插入。为什么更新不起作用?
- c# - 使用任何排序算法对游戏对象列表进行排序
- response - 'lodash' 的 'cloneDeep' 与 'Fetch API' 中的 Response 的 'clone' 方法
- parsing - 使用 DDL 结构从 ADTF 2 读取数据
- android - firebase-core:12.0.1 未找到
- python - 使用条件在 Python 中拆分字符串
- sql - 我在 BigQuery 中的 JOIN 错误