Top.Mail.Ru
онлайн-митап
19 декабря в 17:00 МСК
Матрица компетенций: как инструмент для развития разработчика

Dynamics 365. Как дать доступ пользователям без прав администратора к дополнительной информации о форме

Закладка Администрирование

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

Причина проблемы

Он не имеет доступа к административной части, где содержится информация, которая требуется. В этом случае, это ни так легко, как просто найти объект безопасности, который контролирует доступ к данной части. Сначала необходимо найти форму, которая отображает информацию о форме.  Эта форма называется «FormControlPersonalization». В коде данной формы можно увидеть следующее:

Становится понятно, почему не отображается административная информация. Когда диалог запускается, то проверяется, указана ли роль системного администратора для текущего пользователя. Если пользователь не подписан на данную роль, то административная часть скрывается.

Реализация решения

Что можно сделать, чтобы управлять отображением этой части. Можно создать событие PostHandler для метода loadControlsState. Созданное событие будет вызываться уже после успешного выполнения метода loadControlsState. Событие будет решать две задачи:

  • Делать административную часть видимой.
  • Загружать корректные значения в поля, которые располагаются в административной части.

Первым делом получаем объект FormRun и находим необходимый элемент на форме, чтобы сделать его видимым.

Далее требуется только вызвать метод loadAdminInformation, но здесь ожидаются сложности. Метод имеет модификатор доступа private, поэтому нет возможности его вызывать из другого класса.  В связи с этим, необходимо воссоздать основную функциональность приватного метода.

Создадим новый класс и добавим в него следующий код:

[PostHandlerFor(formStr(FormControlPersonalization), formMethodStr(FormControlPersonalization, loadControlsState))]
public static void FormControlPersonalization_Post_loadConstrolsState(XppPrePostArgs _args)
{
  FpFormControlPersonalization_Ext ext = new FpFormControlPersonalization_Ext();
  FormRun fr = _args.getThis();
  FormTabPageControl adminControl = fr.design().controlName(formControlStr(FormControlPersonalization, AdministrationTab)) as FormTabPageControl;
  adminControl.visible(true);

  FormControl personalizedControl;
  personalizedControl = fr.args().parmObject();

  FormRun callingForm;
  callingForm = fr.args().caller();

  FormStringControl formName = fr.design().controlName(formControlStr(FormControlPersonalization, FormName)) as FormStringControl;
  formName.text(callingForm.name());

  FormStringControl controlName = fr.design().controlName(formControlStr(FormControlPersonalization, ControlName)) as FormStringControl;
  FormStringControl controlType = fr.design().controlName(formControlStr(FormControlPersonalization, ControlType)) as FormStringControl;
  FormStringControl dataSource = fr.design().controlName(formControlStr(FormControlPersonalization, DataSource)) as FormStringControl;
  FormStringControl dataField = fr.design().controlName(formControlStr(FormControlPersonalization, DataField)) as FormStringControl;
  FormStringControl menuItemName = fr.design().controlName(formControlStr(FormControlPersonalization, MenuItemName)) as FormStringControl;
  FormStringControl menuItemType = fr.design().controlName(formControlStr(FormControlPersonalization, MenuItemType)) as FormStringControl;
  FormStringControl queryName = fr.design().controlName(formControlStr(FormControlPersonalization, QueryName)) as FormStringControl;
  FormStringControl queryString = fr.design().controlName(formControlStr(FormControlPersonalization, QueryString)) as FormStringControl;
  FormStringControl callerName = fr.design().controlName(formControlStr(FormControlPersonalization, CallerName)) as FormStringControl;
  FormStringControl callerType = fr.design().controlName(formControlStr(FormControlPersonalization, CallerType)) as FormStringControl;

  if(personalizedControl)
  {
    ControlName.text(personalizedControl.name());
    System.Type controlDotNetType = any2Object(personalizedControl).GetType();
    ControlType.text(controlDotNetType.Name);
    DataSource.text(personalizedControl.dataSourceObject()? strfmt('%1 (%2)', personalizedControl.dataSourceObject().name(), tableId2Name(personalizedControl.dataSourceObject().table())) : '');
    DataField.text(personalizedControl.fieldBinding()? personalizedControl.fieldBinding().fieldName() : '');
  }
  else
  {
    controlName.text('');
    controlType.text('');
    dataSource.text('');
    dataField.text('');
  }

  if (callingForm.args())
  {
    Args callingFormArgs = callingForm.args();
    MenuItemName.text(callingFormArgs.menuItemName());
    MenuItemType.text(enum2Symbol(enumNum(MenuItemType), callingFormArgs.menuItemType()));
    QueryName.text(callingFormArgs.initialQuery() ? callingFormArgs.initialQuery().modeledQueryName() : '');
    QueryString.text('');
    ext.setDataSourceField(callingForm, queryString);
    CallerName.text(callingFormArgs.callerName());
    CallerType.text(enum2Symbol(enumNum(UtilElementType), callingFormArgs.callerType()));
  }
  else
  {
    MenuItemName.text('');
    MenuItemType.text('');
    QueryName.text('');
    ext.setDataSourceField(callingForm, queryString);
    CallerName.text('');
    CallerType.text('');
  }
}

private void setDataSourceField(FormRun _callingForm, FormStringControl _queryString)
{
  if (_callingForm.dataSource(1))
  {
    FormDataSource fds = _callingForm.dataSource(1);
    QueryString.text(fds.queryRun() ? fds.queryRun().query().toString() : fds.query().toString());
  }
}

После этого любой пользователь сможет просматривать административную часть в информации о форме.

Если нет необходимости давать доступ всем пользователям, то можно реализовать ограничения по ролям.

Источник: https://alexdmeyer.com/2021/05/03/how-to-allow-non-admin-users-to-access-security-features-in-d365fo/

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar