AXForum  
Вернуться   AXForum > Microsoft Dynamics CRM > Dynamics CRM: Разработка
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.07.2014, 13:21   #1  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Конфликт плагина и рабочего процесса
Приветствую, коллеги.

Нужен совет в следующей сложившейся ситуации.
Есть плагин, зарегистрированный на Pre Email Create. Плагин проводит некие манипуляции со связанным с письмом обращением (regarding case). Один из шагов плагина - это обновление связанного обращения (service.Update). Но вот в чём проблема, на шаге апдейта получается рекурсия с другим real-time рабочим процессом, который падает в эксепшн, который в свою очередь не даёт корректно отработать самому плагину. Ниже текст самого эксепшена.
Код:
[Microsoft.Crm.ObjectModel: Microsoft.Crm.ObjectModel.SyncWorkflowExecutionPlugin][7133aad3-f70b-e411-80d9-0050568c1ffc: ]
Starting sync workflow 'Простановка категории организации', Id: 6833aad3-f70b-e411-80d9-0050568c1ffc
Entering UpdateStep1_step: 
Sync workflow 'Простановка категории организации' terminated with error 'Value cannot be null.
Parameter name: culture'
Тут же отмечу, что запуск конфликтного рабочего процесса осуществляется по апдейту одного единственного поля. И, видимо, стартует по событию апдейта обращения, обрабатываемого плагином. Плагином же обновляется атрибут, отличный от атрибута, задействованного в рабочем процессе. Код события апдейта плагина ниже:
Код:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(true));
regardingCase["dt_ustomerrating"] = userRating.ToString();
service.Update(regardingCase);
Я пытался ограничить количество передаваемых на апдейт атрибутов:
Код:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(new string[] { "dt_ustomerrating" }));
Но это решение выкидывало в эксепшн "The given key was not present in the dictionary". Плюс, на сколько я понял из курения МСДН, ColumnSet возвращает только not null значения. А у меня по основному сценарию атрибут "dt_ustomerrating" не зполнен. Но даже если и заполнен, результат всё равно "The given key was not present in the dictionary".
Ну и на последок, если я отключаю конфликтный рабочий процесс, то плагин отрабатывает без ошибок и проблем. Ещё пробовал утилитой XrmToolBox понизить приоритет запуска проблемного р\п, но это тоже не помогло.

Как лучше всего выйти из сложившейся ситуации и сделать так, чтобы р\п и плагин не мешали и не конфликтовали друг с другом? Заранее благодарю за помощь .
Старый 15.07.2014, 14:02   #2  
Артем Enot Грунин is offline
Артем Enot Грунин
Moderator
Аватар для Артем Enot Грунин
MCBMSS
Злыдни
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,912 / 623 (28) +++++++
Регистрация: 16.08.2007
Адрес: Пермь!
Записей в блоге: 151
Добрый день. Я бы рекомендовал вам запрашивать и обновлять только те атрибуты, которые нужно. Во-первых, такое решение более производительно, во-вторых, оно не будет приводить к срабатыванию лишних плагинов и процессов (так как вы не обновите атрибуты, на которые они подписаны).

Исключение выкидывает не решение, а ваш код. Всегда проверяйте наличие атрибута в выборке, прежде чем к нему обратится. Ну или используйте безопасный метод GetAttributeValue. Если не ошибаюсь, он не выбрасывает исключений.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия.

MS Certified Dirty Magic Professional
За это сообщение автора поблагодарили: magicandy (1).
Старый 15.07.2014, 18:11   #3  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Артем, спасибо.

Цитата:
Я бы рекомендовал вам запрашивать и обновлять только те атрибуты, которые нужно.
Дык, я пытаюсь . Разве это не оно?
Код:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(new string[] { "dt_ustomerrating" }));
Цитата:
Всегда проверяйте наличие атрибута в выборке, прежде чем к нему обратится.
Не совсем понимаю необходимость этого действия. Ведь я уверен, что атрибут там есть (а вот значения может и не быть). В частности "dt_ustomerrating". Или проверка изменит ситуацию в моём случае?

Цитата:
Ну или используйте безопасный метод GetAttributeValue.
Тут тоже позвольте вопросик. Я правда не знаю .
Ведь метод service.Update обновляет сущность. А GetAttributeValue возвращает значение атрибута. Поправьте меня, если я не прав. в service.Retrieve я получаю сущность, а потом её же обновляю. А как я обновлю сущность по GetAttributeValue? Возможно, простенький примерчик поставит меня на путь истины

Ещё раз спасибо!
Старый 15.07.2014, 18:46   #4  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Цитата:
Сообщение от magicandy Посмотреть сообщение
Артем, спасибо.
Не совсем понимаю необходимость этого действия. Ведь я уверен, что атрибут там есть (а вот значения может и не быть). В частности "dt_ustomerrating". Или проверка изменит ситуацию в моём случае?
Если поле пустое (равно null) то атрибута в коллекции вы не найдёте. Именно поэтому надо или проверять наличие атрибута.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
За это сообщение автора поблагодарили: magicandy (1).
Старый 15.07.2014, 19:03   #5  
Артем Enot Грунин is offline
Артем Enot Грунин
Moderator
Аватар для Артем Enot Грунин
MCBMSS
Злыдни
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,912 / 623 (28) +++++++
Регистрация: 16.08.2007
Адрес: Пермь!
Записей в блоге: 151
Цитата:
Сообщение от magicandy Посмотреть сообщение
Разве это не оно?
Код:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(new string[] { "dt_ustomerrating" }));
Оно. Так и нужно делать.
Цитата:
Сообщение от magicandy Посмотреть сообщение
Не совсем понимаю необходимость этого действия. Ведь я уверен, что атрибут там есть (а вот значения может и не быть). В частности "dt_ustomerrating". Или проверка изменит ситуацию в моём случае?
Беда в том, что для экономии трафика, даже если вы просили вернуть вам только 1 атрибут, система не вернет вам значение этого атрибута, если он пустой.
Цитата:
Сообщение от magicandy Посмотреть сообщение
Ведь метод service.Update обновляет сущность. А GetAttributeValue возвращает значение атрибута. Поправьте меня, если я не прав. в service.Retrieve я получаю сущность, а потом её же обновляю. А как я обновлю сущность по GetAttributeValue?
Я полагаю, сейчас вы делаете что-то вроде:
X++:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(new string[] { "dt_ustomerrating" }));
ustomerrating = regardingCase["dt_ustomerrating"];
В результате, если поле было постое вы получаете исключение. Поэтому, нужно делать вот так:
X++:
regardingCase = service.Retrieve("incident", regardingCaseId, new ColumnSet(new string[] { "dt_ustomerrating" }));
ustomerrating = regardingCase.GetAttributeValue<Type>("dt_ustomerrating");
Аналогично при обновлении любого атрибута. Если его нет в коллекции, а вы пытаетесь его обновить, то будет ошибка:
X++:
regardingCase.["someattribute"] = value;
Так что лучше делать:
X++:
regardingCase.SetAttributeValue("someattribute", value);
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия.

MS Certified Dirty Magic Professional
Старый 17.07.2014, 10:57   #6  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Коллеги, всем большое спасибо за рекомендации.
Всё получилось и работает.
Старый 17.07.2014, 19:42   #7  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Коллеги, снова требуется помощь. Решил не создавать новую тему, так как вопрос касается того же плагина. Возникла необходимость получить имя отправителя письма (from). Плагин зарегистрирован на PreCreate. Получить пытаюсь так.
X++:
var from = (EntityCollection)entity.Attributes["from"];
var fromEntity = from.Entities[0];
var fromName = ((EntityReference)fromEntity.Attributes["partyid"]).Name;
fromName в результате null . Однако, при ручном создании письма этот механизм работает. Получается, что на шаге PreCreate связь с ActivityParty письма ещё не установлена? Какой выход? Переделывать плагин на PostCreate? Без вариантов?
Старый 17.07.2014, 19:53   #8  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Попробуйте так :

X++:
var partyid = fromEntity["partyid"] as EntityReference;
var entity = service.Retrieve("account"  "contact", partyid.Id, new ColumnSet("name"  "fullname");
var fullName = entity.GetAttributeValue<string>("name"  "fullname");
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
Старый 17.07.2014, 20:25   #9  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Чёрт возьми, работает!
Если не сложно, не подскажите почему мой вариант не давал результата, а ваш очень даже? Логика ведь та же. Я тоже пытался через service.Retrieve, но не те гуиды подставлял видимо.
Большое спасибо.
Старый 17.07.2014, 20:34   #10  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Свойство Name заполняется только при Retrieve/RetrieveMuluple, но не при Create.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
Старый 17.07.2014, 20:59   #11  
magicandy is offline
magicandy
Участник
 
111 / 12 (1) ++
Регистрация: 15.07.2014
Спасибо. Не совсем понятно правда, почему мой вариант возвращал Name при ручном сценарии создания письма .
И ещё один вопросик, который давно не даёт покоя. В чём разница между:
X++:
var fromName = entityz.GetAttributeValue<string>("name");
и
X++:
var fromName = (string)entityz.Attributes["name"];
?
Какая конструкция наиболее предпочтительна, если речь идёт о разработке под ЦРМ2013? Специально опробовал сейчас оба варианта. И оба рабочие.
Старый 17.07.2014, 21:17   #12  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Почитайте это.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Помощь в настройке плагина CRM для Outlook joyer Dynamics CRM: Администрирование 6 27.02.2013 23:11
Неконтролируемый многократный запуск бизнес-процесса. Uoa Dynamics CRM: Функционал 5 30.11.2011 14:28
Под кем выполняется код плагина? Tony Green Dynamics CRM: Разработка 1 14.02.2011 18:41
Модификая контекста плагина ZooY Dynamics CRM: Разработка 3 28.09.2008 13:52
Мир CRM: Автоматизирование добавления основного контакта при помощи Бизнес-Процесса Blog bot Dynamics CRM: Blogs 0 31.07.2008 02:08

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 17:02.