【发布时间】:2018-06-19 14:12:32
【问题描述】:
更新 我从这个论坛以及 Dynamics 论坛中提取了一些信息,并且我的代码可以正常工作。我的代码中的主要问题是我只查看了 preImage,但在大多数情况下,三个值之一将被更新,这意味着我无法定位该特定字段的 preImage。我将逻辑更改为使用 Collection 属性(更新的值)如果它已更新,但如果它没有更新则使用 PreImage 值 - 这使得代码工作,并且每次都会触发更新 - 不再需要触发插件两次!这是更新后的代码 - 它比原始代码更高效、更简洁(向下滚动以查看旧/非工作代码)。我还添加了一些 cmets 使其更容易理解。感谢所有人的帮助(无论是在 SO 上,还是在 Dynamics 论坛上!)
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
using System.ServiceModel;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace CLIENTNTE
{
public class NTEExceedance : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
Decimal nte_percent = 0;
Decimal subtotalDecimal = 0;
Decimal nteDecimal = 0;
Decimal amountDiffDecimal = 0;
Decimal percentDifference = 0;
try
{
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];
//if entity is not Work Order, return. Prevents plugin firing on wrong entity (in case of wrong registration in plugin registration tool)
if (entity.LogicalName != "msdyn_workorder")
{
return;
}
//get preimage of WO Entity
Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
//logic for when updated attribute is NTE Amount
if (entity.Attributes.Contains("CLIENT_nteamount") == true)
{
nteDecimal = entity.GetAttributeValue<Money>("CLIENT_nteamount").Value;
}
else
{
nteDecimal = preMessageImage.GetAttributeValue<Money>("CLIENT_nteamount").Value;
}
//logic for when updated attribute is NTE Percent
if (entity.Attributes.Contains("CLIENT_ntepercent") == true)
{
nte_percent = entity.GetAttributeValue<Decimal>("CLIENT_ntepercent");
}
else
{
nte_percent = preMessageImage.GetAttributeValue<Decimal>("CLIENT_ntepercent");
}
//logic for when updated attribute is Estimate Subtotal Amount
if (entity.Attributes.Contains("msdyn_estimatesubtotalamount") == true)
{
subtotalDecimal = entity.GetAttributeValue<Money>("msdyn_estimatesubtotalamount").Value;
}
else
{
subtotalDecimal = preMessageImage.GetAttributeValue<Money>("msdyn_estimatesubtotalamount").Value;
}
//calculation of Amount Difference, and Percent Difference
amountDiffDecimal = (subtotalDecimal - nteDecimal);
percentDifference = ((amountDiffDecimal / nteDecimal) * 100);
//Comparison logic to update the NTE Exceeded flag
if (percentDifference > nte_percent)
{
entity["CLIENT_nteexceeded"] = true;
}
if (percentDifference <= nte_percent)
{
entity["CLIENT_nteexceeded"] = false;
}
}
}
catch (FaultException<OrganizationServiceFault> e)
{
//write errors to the CRM Plugin Trace Log
tracingService.Trace("CLIENTPlugin - Update NTEExceededNonCalc: {0}", e.ToString());
//Throw error through UI
throw new InvalidPluginExecutionException("Error, Please See Plugin Log");
}
}
}
}
原帖 再来一次!昨天,我意识到我不使用 PreImage 来获取未包含在更新的属性集合中的值的方法中的错误 - SCORE!现在,插件工作,但它只在我触发插件时才工作。
所以,似乎插件实际上正在触发(我可以在设置 > 插件配置文件中看到插件配置文件),但没有执行我需要的更新,直到我第二次触发插件。这似乎发生在我正在监听的所有 3 个属性上,并且每个属性都需要更新两次(例如,如果我更新属性 1,插件不会更新我的值,如果我再更新属性 2,插件仍然不会更新我的值,直到我再次重新更新属性 1 或属性 2)。当我分析/调试我的代码并逐步执行它时,我可以看到 if 语句被命中,并且更新实体字段的代码行也正在执行 - 但无论出于何种原因,它都没有设置值 ( CLIENT_nteexceeded = true or false) 直到我第二次触发它。如果它根本不更新实体记录值会更有意义,而且我错过了某种类型的“更新”消息(我玩过 service.Entity.Update() 但它似乎没有应用到这个插件)
我对 CRMDEV 还是比较陌生,所以请原谅这个愚蠢的问题。这对我来说似乎是一个非常愚蠢的问题,而且它一定是我错过的一些小问题。关于为什么这会迫使我触发两次代码以执行更新的任何想法?
这是插件步骤的配置。这三个过滤器属性是代码中引用的那些。同样,插件工作正常,只是不会每次都更新记录。
下面的代码(删除了对客户名称的引用)
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
using System.ServiceModel;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace CLIENTNTE
{
public class NTEExceedance : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
//Extract the tracing service for use in debugging sandboxed plug-ins.
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
Money subtotal = null;
Money nte = null;
Decimal nte_percent = 0;
Decimal subtotalDecimal = 0;
Decimal nteDecimal = 0;
Decimal amountDiffDecimal = 0;
Decimal percentDifference = 0;
try
{
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName == "msdyn_workorder")
{
//code fires onChange of NTE Amount (same logic will apply to NTE % and Est Subtotal Amount)
if (entity.Attributes.Contains("CLIENT_nteamount") == true)
{
//String NewValue = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()));
// String NewSubTotal = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["msdyn_estimatesubtotalamount"].ToString());
//String NewNTE = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_nteamount"].ToString());
//String Newpercent = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_ntepercent"].ToString());
if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
{
Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
// get topic field value before database update perform
//pretopic = (String)preMessageImage.Attributes["subject"];
subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
}
//old way of trying to get values NON IMAGE
//subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
//nte = (Money)entity.Attributes["CLIENT_nteamount"];
//nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];
subtotalDecimal = subtotal.Value;
nteDecimal = nte.Value;
amountDiffDecimal = (subtotalDecimal - nteDecimal);
percentDifference = ((amountDiffDecimal / nteDecimal) * 100);
if (percentDifference > nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = true;
}
if (percentDifference <= nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = false;
}
}
if (entity.Attributes.Contains("CLIENT_ntepercent") == true)
{
if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
{
Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
// get topic field value before database update perform
//pretopic = (String)preMessageImage.Attributes["subject"];
subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
}
//old way of trying to get values NON IMAGE
//subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
//nte = (Money)entity.Attributes["CLIENT_nteamount"];
//nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];
subtotalDecimal = subtotal.Value;
nteDecimal = nte.Value;
amountDiffDecimal = (subtotalDecimal - nteDecimal);
percentDifference = ((amountDiffDecimal / nteDecimal) * 100);
if (percentDifference > nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = true;
}
if (percentDifference <= nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = false;
}
}
if (entity.Attributes.Contains("msdyn_estimatesubtotalamount") == true)
{
if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
{
Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
}
//old way of trying to get values NON IMAGE
//subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
//nte = (Money)entity.Attributes["CLIENT_nteamount"];
//nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];
subtotalDecimal = subtotal.Value;
nteDecimal = nte.Value;
amountDiffDecimal = (subtotalDecimal - nteDecimal);
percentDifference = ((amountDiffDecimal / nteDecimal) * 100);
if (percentDifference > nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = true;
}
if (percentDifference <= nte_percent)
{
//know this snippet works
entity["CLIENT_nteexceeded"] = false;
}
}
}
}
}
catch (FaultException<OrganizationServiceFault> e)
{
tracingService.Trace("CLIENTPlugin - Update NTEExceededNonCalc: {0}", e.ToString());
throw e;
}
}
}
}
【问题讨论】:
-
只是一个疯狂的猜测。尝试将执行管道作为 PreOperation 而不是 PreValidation 并查看..
-
感谢@ArunVinoth。我不知道为什么,但是当我更新我的步骤以使用 PreOperation(或其他任何东西)时,我开始在 CRM 中遇到错误。我想我必须注销并重新注册整个事情才能更改执行管道?奇怪,但我昨天正在尝试这个确切的东西,并遇到了同样的问题。我今天不得不删除并重新添加,但没有将其切换到 PreOp。我将在重新删除后立即尝试
-
是的,只是重新添加了插件并将其设置为 PreOperation,它仍然表现出相同的行为。多么令人沮丧!我不知道为什么这个东西不会触发更新,除非它第二次执行插件....
-
在您的问题中尽量简洁...当您寻求帮助时,少即是多。
-
感谢@Daryl 的建议。我总是试图平衡提供足够的信息和太少的信息。我觉得我总是必须在问题中提供尽可能多的信息,以便为那些善意提供帮助的人描绘整个画面。以后我会努力删掉多余的文字。
标签: c# dynamics-crm microsoft-dynamics dynamics-crm-online