Работа над настраиваемым рабочим процессом Dynamics CRM, который обновляет поле «Изменено» - требуется помощь в отладке - PullRequest
0 голосов
/ 29 июня 2019

Я работаю над Dynamics CRM CWA , который обновляет поле «Изменено» на основе текстового поля «Подготовлено».В настоящее время у меня есть 3 ошибки, которые мне нужна помощь в отладке (см. Ниже).Они могут быть довольно легко исправить, но я довольно плохо знаком с кодированием.Любая помощь по устранению ошибок будет принята с благодарностью.Спасибо!

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using System.Runtime.Serialization;

namespace KED365.Workflows
{


    /// </summary>    
    public class ModifiedBy : WorkFlowActivityBase
    {
        private Guid contactid;

        [Input("User Full Name")]
        public InArgument<string> UserFullName { get; set; }


        /// <summary>
        /// Executes the WorkFlow.
        /// </summary>
        /// <param name="crmWorkflowContext">The <see cref="LocalWorkflowContext"/> which contains the
        /// <param name="executionContext" > <see cref="CodeActivityContext"/>
        /// </param>       
        /// <remarks>
        /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
        /// The WorkFlow's Execute method should be written to be stateless as the constructor
        /// is not called for every invocation of the WorkFlow. Also, multiple system threads
        /// could execute the WorkFlow at the same time. All per invocation state information
        /// is stored in the context. This means that you should not use global variables in WorkFlows.
        /// </remarks>
        protected override void Execute(CodeActivityContext activityContext, IWorkflowContext workflowContext, IOrganizationService orgService, ITracingService tracingService)
        {
            //get entity record for which plugin was fired
            Entity _target = (Entity)workflowContext.InputParameters["Target"];


            //check if portaluser name is to be obtained from custom createby or from custom modifiedby
            if (workflowContext.MessageName.ToUpper() == "CREATE")
            {
                contactid = _target.Attributes.Contains("new_createdby") ? _target.GetAttributeValue<EntityReference>("new_createdby").Id : Guid.Empty;
            }
            else
            {
                contactid = _target.Attributes.Contains("new_modifiedby") ? _target.GetAttributeValue<EntityReference>("new_modifiedby").Id : Guid.Empty;
            }

            //retrieve contact fullname from contactid
            var _contact = activityContext.CreateQuery("contact").Where(c => c.GetAttributeValue<Guid>("contactid").Equals(contactid)).FirstOrDefault();


            if (_contact != null)
            {
                if (_contact.Attributes.Contains("fullname"))
                {
                    fullname = _contact.GetAttributeValue<string>("fullname");
                }

                //retrieve Systemuser that has same name as that of new_portalcreatedby/ //new_portalmodifiedby
                Entity _user = context.CreateQuery("systemuser").Where(e => e.GetAttributeValue<string>("fullname").Equals(fullname)).FirstOrDefault();

                if (_user != null)
                {

                    //check if we need to update createdby or modifiedby
                    if (workflowContext.MessageName.ToUpper() == "CREATE")
                    {
                        _target["createdby"] = _user.ToEntityReference();
                    }
                    else
                    {
                        _target["modifiedby"] = _user.ToEntityReference();
                    }

                    //assign new target to plugin executioncontext
                    workflowContext.InputParameters["Target"] = _target;
                }
            }
        }
    }
}

Ошибка 1:

Код серьезности Описание Ошибка состояния подавления строки файла проекта CS1061 «CodeActivityContext» не содержит определения для «CreateQuery»'и не найден метод расширения' CreateQuery ', принимающий первый аргумент типа' CodeActivityContext '(отсутствует директива using или ссылка на сборку?) Рабочие процессы C: \ Users \ tgiard \ Downloads \ GetUserByName-master \ GetUserByName-master\ Workflows \ ModifiedBy.cs 68 Активно

Ошибка 2:

Код серьезности Описание Файл проекта Состояние подавления строки Ошибка CS0103 Имя «полное имя»не существует в текущем контексте. Рабочие процессы C: \ Users \ tgiard \ Downloads \ GetUserByName-master \ GetUserByName-master \ Workflows \ ModifiedBy.cs 75 Активные

Ошибка 3:

Код серьезности Описание Файл проекта Состояние подавления строки файла Ошибка CS0103 Имя «контекст» не существует в текущем контексте Workflows C: \ Users \ tgiard \ Downloads \ GetUserByName-master \ GetUserByName-master \ Workflows \ ModifiedBy.cs 79 Активно

Ответы [ 2 ]

1 голос
/ 01 июля 2019

Вот некоторые отзывы о ваших проблемах:

Ошибка 1 - CodeActivityContext не содержит определения для CreateQuery
Эта проблемасвязанные со строками:

var _contact = activityContext.CreateQuery("contact").Where(c => c.GetAttributeValue<Guid>("contactid").Equals(contactid)).FirstOrDefault();

и

Entity _user = context.CreateQuery("systemuser").Where(e => e.GetAttributeValue<string>("fullname").Equals(fullname)).FirstOrDefault();

Я не знаю, что это за метод, но у вас есть лучшие варианты;для контакта у вас уже есть гид, так что вы можете просто использовать Retrieve ():

    var _contact = orgService.Retrieve("contact", contactid, new ColumnSet("fullname"));

А для системного пользователя напишите фильтрацию QueryExpression по полному имени:

var query = new QueryExpression("systemuser"):
query.Criteria.AddCondition("fullname", ConditionOperator.Equal, fullname);
var _user = orgService.RetrieveMultiple(query).Entities.FirstOrDefault();

Ошибка 2: Имя 'полное имя' не существует в текущем контексте
Это базовый C #, перед использованием его необходимо создать экземпляр вашей переменной:

string fullname;

Ошибка 3: Имя 'context' не существует в текущем контексте
Ironic и true.Это должно быть ActivityContext, но мы уже исправили эту проблему в изменениях, которые мы сделали для ошибки 1.

Entity _user = context.CreateQuery("systemuser").Where(e => e.GetAttributeValue<string>("fullname").Equals(fullname)).FirstOrDefault();
0 голосов
/ 06 июля 2019

Как правильно указал Зак Мач, рекомендуется использовать предварительную операцию. Также кажется странным случай, когда вы извлекаете имя контакта и сопоставляете его с пользователем. Вместо этого вы можете изменить тип поля на ссылку пользователя, добавить поле пользователя к полученному контакту или добавить код, соответствующий контакту с пользователем. Таким образом, у вас не будет проблем с пользователями с одинаковыми именами или опечатками.

Ниже приведена информация о вашем рабочем процессе, преобразованном в плагин Pre-Operation.

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;

namespace KED365.Plugins
{
    public class CreateUpdateContact : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            var service = factory.CreateOrganizationService(context.UserId);
            tracingService.Trace("Start plugin");

            tracingService.Trace("Validate Target");
            if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity))
                return;

            tracingService.Trace("Retrieve Target");
            var target = (Entity)context.InputParameters["Target"];

            String message = context.MessageName.ToLower();

            SetCreatedByAndModifiedBy(tracingService, service, target, message);
        }

        private void SetCreatedByAndModifiedBy(ITracingService tracingService, IOrganizationService service, Entity target, string message)
        {
            tracingService.Trace("Start SetPriceList");
            tracingService.Trace("Validate Message is Create or Update");
            if (!message.Equals("create", StringComparison.OrdinalIgnoreCase) && !message.Equals("update", StringComparison.OrdinalIgnoreCase))
                return;

            tracingService.Trace("Retrieve Attributes");
            var createdByReference = target.GetAttributeValue<EntityReference>("new_createdby");
            var modifiedByReference = target.GetAttributeValue<EntityReference>("new_modifiedby");

            tracingService.Trace("Retrieve And Set User for Created By");
            RetrieveAndSetUser(tracingService, service, target, createdByReference, "createdby");

            tracingService.Trace("Retrieve And Set User for Modified By");
            RetrieveAndSetUser(tracingService, service, target, modifiedByReference, "modifiedby");
        }

        private void RetrieveAndSetUser(ITracingService tracingService, IOrganizationService service, Entity target, EntityReference reference, string targetAttribute)
        {
            tracingService.Trace("Validating Reference");
            if (reference == null)
                return;

            tracingService.Trace("Retrieving and Validating User");
            var user = RetrieveUserByName(service, reference.Name, new ColumnSet(false));
            if (user == null)
                return;

            tracingService.Trace("Setting Target Attribute");
            target[targetAttribute] = user.ToEntityReference();
        }

        private Entity RetrieveUserByName(IOrganizationService service, string name, ColumnSet columns)
        {
            var query = new QueryExpression
            {
                EntityName = "systemuser",
                ColumnSet = columns,
                Criteria = new FilterExpression
                {
                    FilterOperator = LogicalOperator.And,
                    Conditions =
                    {
                        new ConditionExpression
                        {
                            AttributeName = "fullname",
                            Operator = ConditionOperator.Equal,
                            Values = { name }
                        }
                    }
                }
            };

            var retrieveResponse = service.RetrieveMultiple(query);
            if (retrieveResponse.Entities.Count == 1)
            {
                return retrieveResponse.Entities.FirstOrDefault();
            }
            else
            {
                // Alternatively you can thrown an error as you have unexpectedly multiple matches
                return null;
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...