簡體   English   中英

Dynamics 365 CRM Online-插件僅每隔一次觸發執行更新

[英]Dynamics 365 CRM Online - Plugin Only Performs Update Every Other Time it is Triggered

更新我從該論壇以及Dynamics論壇中獲取了一些信息,並且我的代碼可以正常工作。 代碼中的主要問題是我只查看了preImage,但是在大多數情況下,這三個值之一將被更新,這意味着我無法針對該特定字段的preImage。 我更改了邏輯以使用Collection屬性(更新值)(如果已更新),但是使用PreImage值(如果未更新)-這使代碼起作用,並且每次都會觸發更新-不再需要觸發插件兩次! 這是更新后的代碼-比原始代碼更有效,更簡潔(向下滾動以查看舊的/無效的代碼)。 我還添加了一些評論,以使其更易於理解。 感謝所有人的幫助(無論是在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或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;
            }
        }
    }

}

我將幫助您了解CRM執行管道的工作方式。 然后,您可以在trace / Audit / profiler的幫助下進行故障排除,以找出失敗的地方。

基本上,您是在預驗證/預操作階段中,在DB事務之前攔截從CRM UI發生的service.Update()平台調用。 然后根據業務需要進行數據處理,並在目標實體本身中設置額外的屬性值。 這避免了另一個顯式的額外service.Update()調用並反過來循環死鎖。

如果有任何異常,則您正在登錄跟蹤並拋出該異常。 我建議將其更改為InvalidPluginExecutionException ,您將在UI彈出窗口中看到該InvalidPluginExecutionException 這將回滾事務,這意味着不會保存數據。

此外,為了更好地理解-記錄每個條件語句,變量值等,以查看發生問題的確切跟蹤日志。

更新/回答我從該論壇以及Dynamics論壇中獲取了一些信息,並且我的代碼可以正常工作。 代碼中的主要問題是我只查看了preImage,但是在大多數情況下,這三個值之一將被更新,這意味着我無法針對該特定字段的preImage。 我更改了邏輯以使用Collection屬性(更新值)(如果已更新),但是使用PreImage值(如果未更新)-這使代碼起作用,並且每次都會觸發更新-不再需要觸發插件兩次! 這是更新后的代碼-比原始代碼更有效,更簡潔(向下滾動以查看舊的/無效的代碼)。 我還添加了一些評論,以使其更易於理解。 感謝所有人的幫助(無論是在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");
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM