Dynamics 365 - плагин не обновляет значения

Я гнался за этим со вчерашнего дня, и ничего не имеет смысла. Я прошел через различные варианты того, как может выглядеть код - изменил функцию типа Decimal на String и вернул String вместо decimal, использовал десятичное число, жестко закодировал значение в операторе if (без использования переменной), и используя саму переменную, но ничего не работает. Если я просто установил значение полей в начале блока try и не выполняю никаких логических действий, поля будут обновлены. По мере того, как я просматриваю код с помощью профилей плагинов / отладки в инструменте регистрации плагинов, я вижу, что строки кода для установки значений выполняются, и никаких исключений не генерируется, но, опять же, значения не обновляются. Я даже пробовал добавить service.Update (entity); но это тоже не сработало (и когда я установил значения полей без какой-либо логики, мне не понадобился вызов service.Update для сохранения значений).

Поле, в которое я пытаюсь записать в CRM, имеет тип Decimal с точностью до 2. Конечно, десятичные типы в C # имеют точность 8 или 10, поэтому я даже пытался обрезать десятичную дробь, преобразовать десятичную дробь в строку и т. Д. И т. Д., Но ничего не работает.

Есть идеи, которые помогут мне понять, что здесь происходит?

Я разместил простейшую версию своего кода прямо здесь, прежде чем я пошел и изменил функцию типа Decimal на строку и т. Д.

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System.Net;
using System.Net.Mail;




namespace ClientNTE
{
    public class UpdateVals : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));


            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {

                Entity entity = (Entity)context.InputParameters["Target"];

                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));


                try
                {
                    //Get current record's GUID, which will always be in the attributes collection
                    Guid MainEntityID = new Guid(entity["msdyn_workorderid"].ToString());

                    //Get related entity record's GUID from generic field value grabber function against the main entity

                    Guid RefEntityID = GetGUIDFieldValueFrmID(service, "msdyn_workorder", "msdyn_workorderid", MainEntityID, "msdyn_agreement");

                    //if it has a value, continue

                    if (RefEntityID != Guid.Empty)
                    {
                        Decimal RefEntityFieldValue = GetDecFieldValueFrmID(service, "msdyn_agreement", "msdyn_agreementid", RefEntityID, "client_ntepercent");

                        //if it has a value, continue

                        if (RefEntityFieldValue > -99999999)
                        {
                            entity["client_ntepercent"] = RefEntityFieldValue;
                        }
                    }

                }
                catch (Exception ex)
                {
                    //write errors to the CRM Plugin Trace Log
                    tracingService.Trace("clientNTE - Agreement To Work Order - ", ex.ToString());
                    //Throw error through UI
                    throw new InvalidPluginExecutionException("Error, Please See Plugin Log");
                }
            }
        }

        public Guid GetGUIDFieldValueFrmID(IOrganizationService svc, String EntityNm, String EntityIDField, Guid EntityIDValue, String ReturnFieldNm)
        {
            Guid retval = Guid.Empty;

            try
            {
                OrganizationServiceContext orgContext = new OrganizationServiceContext(svc);

                var ReturnRecords = from a in orgContext.CreateQuery(EntityNm)
                                    where (Guid)a[EntityIDField] == EntityIDValue
                                    select new
                                    {
                                        FieldVal = a[ReturnFieldNm]
                                    };

                if (ReturnRecords != null)
                {
                    foreach (var EvalRec in ReturnRecords)
                    {
                        retval = ((Microsoft.Xrm.Sdk.EntityReference)EvalRec.FieldVal).Id;
                    }
                }
                else
                {
                    retval = Guid.Empty;
                }


            }
            catch (Exception ex)
            {
                retval = Guid.Empty;
                //Throw error through UI
                throw new InvalidPluginExecutionException(ex.ToString());
            }

            return retval;
        }

        public Decimal GetDecFieldValueFrmID(IOrganizationService svc, String EntityNm, String EntityIDField, Guid EntityIDValue, String ReturnFieldNm)
        {
            Decimal retval = -99999999;

            try
            {
                OrganizationServiceContext orgContext = new OrganizationServiceContext(svc);

                var ReturnRecords = from a in orgContext.CreateQuery(EntityNm)
                                    where (Guid)a[EntityIDField] == EntityIDValue
                                    select new
                                    {
                                        FieldVal = a[ReturnFieldNm]
                                    };

                if (ReturnRecords != null)
                {
                    foreach (var EvalRec in ReturnRecords)
                    {
                        retval = Convert.ToDecimal(EvalRec.FieldVal);
                    }
                }
                else
                {
                    retval = -99999999;
                }


            }
            catch (Exception ex)
            {
                retval = -99999999;
                //Throw error through UI
                throw new InvalidPluginExecutionException(ex.ToString());
            }

            return retval;
        }

        //public static Boolean UpdateParentRecord(IOrganizationService svc, Guid ParentRecordID, String FieldValue)
        //{

        //    Boolean retval = false;

        //    try
        //    {
        //        Entity parent_entityrec = new Entity("parent_entity");

        //        parent_entityrec["fieldtoupdate"] = FieldValue;

        //        svc.Update(parent_entityrec);

        //        retval = true;

        //    }

        //    catch (Exception ex)
        //    {
        //        retval = false;
        //    }

        //    return retval;

        //}
    }
}

Теперь здесь вы можете увидеть мой текущий код, в котором я делаю кучу сумасшедших вещей - во-первых, использую функцию типа String, чтобы вернуть десятичное значение. Во-вторых, вызов функции для фактической установки значения, просто чтобы доказать, что с существующей функцией что-то не так (и чтобы упростить форматирование в строке). Что бы я ни делал, я не могу заставить эту чертову работу работать!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System.Net;
using System.Net.Mail;



namespace CLIENTNTE
{
    public class AgreementToWorkOrder : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));


            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {

                Entity entity = (Entity)context.InputParameters["Target"];

                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));


                try
                {
                    //string Num = 12.500000.ToString();
                    //entity["CLIENT_testdecimal"] = Num;
                    //entity["CLIENT_ntepercent"] = Num;

                    //Get current record's GUID, which will always be in the attributes collection
                    Guid MainEntityID = new Guid(entity["msdyn_workorderid"].ToString());

                    //Get related entity record's GUID from generic field value grabber function against the main entity

                    Guid RefEntityID = GetGUIDFieldValueFrmID(service, "msdyn_workorder", "msdyn_workorderid", MainEntityID, "msdyn_agreement");

                    //if it has a value, continue

                    if (RefEntityID != Guid.Empty)
                    {
                        String RefEntityFieldValue = GetDecFieldValueFrmID(service, "msdyn_agreement", "msdyn_agreementid", RefEntityID, "CLIENT_ntepercent");

                        decimal decVal = Convert.ToDecimal(RefEntityFieldValue);
                        //if it has a value, continue
                        if (decVal > -99999999)
                        {
                            // entity["CLIENT_ntepercent"] = RefEntityFieldValue;
                            // entity["CLIENT_ntepercent"] = "12.5";// RefEntityFieldValue;
                            //entity["CLIENT_testdecimal"] = "13.5";// RefEntityFieldValue;
                            setDecimal(RefEntityFieldValue, serviceProvider);
                            //service.Update(entity);
                        } 
                    }

                } 
                catch (Exception ex)
                {
                    //write errors to the CRM Plugin Trace Log
                    tracingService.Trace("CLIENTNTE - Agreement To Work Order - ", ex.ToString());
                    //Throw error through UI
                    throw new InvalidPluginExecutionException("Error, Please See Plugin Log");
                }
            }
        }

        public void setDecimal(String RefEntityFieldValue, IServiceProvider serviceProvider)
        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            //IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            //IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            //ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            Entity entity = (Entity)context.InputParameters["Target"];
            //Guid MainEntityID = new Guid(entity["msdyn_workorderid"].ToString());
            //Guid RefEntityID = GetGUIDFieldValueFrmID(service, "msdyn_workorder", "msdyn_workorderid", MainEntityID, "msdyn_agreement");

            //String RefEntityFieldValue = GetDecFieldValueFrmID(service, "msdyn_agreement", "msdyn_agreementid", RefEntityID, "CLIENT_ntepercent"); */

            // entity["CLIENT_testdecimal"] = RefEntityFieldValue;
            entity["CLIENT_testdecimal"] = 12;
            entity["CLIENT_ntepercent"] = RefEntityFieldValue;


        }

        public Guid GetGUIDFieldValueFrmID(IOrganizationService svc, String EntityNm, String EntityIDField, Guid EntityIDValue, String ReturnFieldNm)
        {
            Guid retval = Guid.Empty;

            try
            {
                OrganizationServiceContext orgContext = new OrganizationServiceContext(svc);

                var ReturnRecords = from a in orgContext.CreateQuery(EntityNm)
                                    where (Guid)a[EntityIDField] == EntityIDValue
                                    select new
                                    {
                                        FieldVal = a[ReturnFieldNm]
                                    };

                if (ReturnRecords != null)
                {
                    foreach (var EvalRec in ReturnRecords)
                    {
                        retval = ((Microsoft.Xrm.Sdk.EntityReference)EvalRec.FieldVal).Id;
                    }
                }
                else
                {
                    retval = Guid.Empty;
                }


            }
            catch (Exception ex)
            {
                retval = Guid.Empty;

                throw new InvalidPluginExecutionException(ex.ToString());
            }

            return retval;
        }

        public String GetDecFieldValueFrmID(IOrganizationService svc, String EntityNm, String EntityIDField, Guid EntityIDValue, String ReturnFieldNm)
        {
            Decimal retval = -99999999;
            String stringVal = "";

            try
            {
                OrganizationServiceContext orgContext = new OrganizationServiceContext(svc);

                var ReturnRecords = from a in orgContext.CreateQuery(EntityNm)
                                    where (Guid)a[EntityIDField] == EntityIDValue
                                    select new
                                    {
                                        FieldVal = a[ReturnFieldNm]
                                    };

                if (ReturnRecords != null)
                {
                    foreach (var EvalRec in ReturnRecords)
                    {
                        retval = Convert.ToDecimal(EvalRec.FieldVal);
                        // stringVal = retval.ToString().TrimEnd('0', '.');
                        stringVal = retval.ToString();
                    }
                }
                else
                {
                    retval = -99999999;
                }


            }
            catch (Exception ex)
            {
                retval = -99999999;
                throw new InvalidPluginExecutionException(ex.ToString());
            }

            return stringVal;
        }
    }
}

Любой вклад приветствуется.


person Brian Frick    schedule 11.09.2018    source источник
comment
Вы проверяли, не был ли ваш шаг плагина зарегистрирован для выполнения почтовой операции? Я не видел вызова метода IOrganizationService.Update, поэтому предполагаю, что это была предварительная операция.   -  person Alessi    schedule 12.09.2018
comment
Я должен был включить больше контекста о моем плагине в исходный пост, плохо. Он запускает OnCreate of Work Orders, а не Update, и просто извлекает данные из соглашения (родительского) для заполнения WO (дочернего). Сопоставление OOB не работало, а использование рабочих процессов мешало другой логике плагина onChange для объекта Work Order, поэтому мне пришлось разбить его на отдельный фрагмент кода. Это зарегистрировано как плагин предварительной проверки (я полностью за то, чтобы это изменить - у меня до сих пор нет полного понимания pre-val, pre-op, post-op).   -  person Brian Frick    schedule 12.09.2018


Ответы (1)


Мой ответ основан на следующих предположениях о вашем коде:

  1. Вариант использования состоит в том, что когда запись msdyn_workorder создается со значением в поле msdyn_agreement, для значения client_ntepercent в рабочем задании должно быть установлено значение client_ntepercent по соглашению.
  2. Плагин регистрируется на этапе Pre-Operation для сообщения Create в сущности msdyn_workorder.

Предлагаемое исправление требует следующих изменений:

  1. Код должен получить значение msdyn_agreement от целевой сущности вместо выполнения запроса на извлечение, поскольку рабочее задание еще не было сохранено в базе данных.

Причина вашей проблемы могла заключаться в том, что вы запрашиваете запись рабочего задания, чтобы получить значение соглашения из предоперационного плагина. Заказ еще не будет сохранен в базе данных.

Обновленный код:

public class UpdateVals : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {

        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity && 
            context.PreEntityImages != null && context.PreEntityImages.Contains("PreImage"))
        {
            Entity target = (Entity)context.InputParameters["Target"];

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            try
            {
                //Get current record's GUID, which will always be in the attributes collection
                Guid MainEntityID = target.GetAttributeValue<Guid>("msdyn_workorderid");

                EntityReference RefEntityID = null;
                if (target.Attributes.Contains("msdyn_agreement"))
                {
                    RefEntityID = target.GetAttributeValue<EntityReference>("msdyn_agreement");
                }

                //if it has a value, continue
                if (RefEntityID != null)
                {
                    Decimal RefEntityFieldValue = GetDecFieldValueFrmID(service, "msdyn_agreement", "msdyn_agreementid", RefEntityID.Id, "client_ntepercent");

                    //if it has a value, continue
                    if (RefEntityFieldValue > -99999999)
                    {
                        target["client_ntepercent"] = RefEntityFieldValue;
                    }
                }

            }
            catch (Exception ex)
            {
                //write errors to the CRM Plugin Trace Log
                tracingService.Trace("clientNTE - Agreement To Work Order - ", ex.ToString());
                //Throw error through UI
                throw new InvalidPluginExecutionException("Error, Please See Plugin Log");
            }
        }
    }

    public Decimal GetDecFieldValueFrmID(IOrganizationService svc, String EntityNm, String EntityIDField, Guid EntityIDValue, String ReturnFieldNm)
    {
        Decimal retval = -99999999;

        try
        {
            OrganizationServiceContext orgContext = new OrganizationServiceContext(svc);

            var ReturnRecords = from a in orgContext.CreateQuery(EntityNm)
                                where (Guid)a[EntityIDField] == EntityIDValue
                                select new
                                {
                                    FieldVal = a[ReturnFieldNm]
                                };

            if (ReturnRecords != null)
            {
                foreach (var EvalRec in ReturnRecords)
                {
                    retval = Convert.ToDecimal(EvalRec.FieldVal);
                }
            }
            else
            {
                retval = -99999999;
            }
        }
        catch (Exception ex)
        {
            retval = -99999999;
            //Throw error through UI
            throw new InvalidPluginExecutionException(ex.ToString());
        }

        return retval;
    }
}
person J Heckman    schedule 11.09.2018
comment
Спасибо, что нашли время пройти через это, особенно потому, что в моем коде отсутствовала некоторая информация. Кроме того, ваше имя звучит знакомо, как будто мы, возможно, работали вместе в прошлом или что-то в этом роде ... В любом случае ... Как я сказал выше, по крайней мере, сейчас это просто запускает OnCreate of WO и извлекает данные вниз из Соглашения в WO. После того, как он был создан, мы не хотим снова обновлять данные из соглашения (мы хотим, чтобы отношение соглашение: wo было «моментом времени», которое пользователи также могут обновлять по мере необходимости). Я собираюсь перенести ваш код в VS и протестировать его. Спасибо! - person Brian Frick; 12.09.2018
comment
@BrianFrick Спасибо за дополнительную информацию. Я обновлю ответ на основе того, что плагин предназначен только для создания. Вопрос должен быть таким же. Запрос рабочего задания в предварительном создании ничего не найдет, поскольку рабочий заказ еще не был сохранен в базе данных. Однако в create нет предварительного изображения, поэтому вы можете просто получить значение соглашения от цели. - person J Heckman; 12.09.2018