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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.12.2017, 22:02   #1  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
D365 FO Ссылка на конкретную запись. Параметры URL
Добрый день! В рамках исследования параметров URL, через которые можно задать те или иные команды системе были найдены следующие интересные моменты:

1. Встроенные команды.
https://community.dynamics.com/ax/b/...url-parameters
В том числе, наиболее интересные:
prt=[partitionID] - указание раздела, в котором будет проводиться работа
cmp=[legal entity] - указание компании, в которой будет проводиться работа
lng=[LanguageId] - указание языка интерфейса. Очень удобно, когда хочется посмотреть как одна и та же надпись выглядит как по-русски, так и по-английски
mi=[menuItem] - указание пункта меню, который требуется вызвать
f=[formName] - указание названия формы, которую нужно открыть напрямую, не через пункт меню
q=[queryString] - запрос, который передается на форму и позволяет отфильтровать данные формы

2. Запрос система может генерить сама (см https://axology.wordpress.com/2016/1...or-operations/). Для этого нужно в параметрах пользователя включить параметр "Автоматическое обновление параметров запроса"
Название: SNAG_Program-0018.png
Просмотров: 1525

Размер: 8.5 Кб
и воспользоваться расширенным фильтром на форме
Нажмите на изображение для увеличения
Название: SNAG_Program-0019.png
Просмотров: 520
Размер:	49.5 Кб
ID:	11798
Запрос зашифрован, однако если его расшифровать - то там будет строка вида Параметр1=Значение1&Параметр2=Значение2, где параметры - это поля фильтра запроса (по сути - предложение WHERE в SQL-запросе). Однако D365 принимает только зашифрованную строку, так что смысла в дешифровке особой нет. Возможно, есть параметры, при которых шифрование отключается - но я их пока не видел (в АХ 2012 и ранее на портале такой параметр был)

3. Каждый запускаемый объект имеет право самостоятельно определять дополнительные параметры URL, которые он готов принять. Пример - см класс SysTableBrowser и параметр TableName:
Нажмите на изображение для увеличения
Название: SNAG_Program-0020.png
Просмотров: 470
Размер:	27.3 Кб
ID:	11799

4. Есть официальная статья Create and use deep links, в которой приводится пример, как сгенерить URL-адрес, открывающий заданный пункт меню с заданным фильтром (Query)

X++:
// gets the generator instance
var generator     = new Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.UrlGenerator();
var currentHost   = new System.Uri(UrlUtility::getUrl());
generator.HostUrl = currentHost.GetLeftPart(System.UriPartial::Authority);
generator.Company = curext();
generator.MenuItemName = <menu item name>;
generator.Partition = getCurrentPartition(); 

// repeat this segment for each datasource to filter
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
requestQueryParameterCollection.AddRequestQueryParameter(
    <datasource name>,
    <field1>, <value1>,
    <field2>, <value2>,
    <field3>, <value3>,
    <field4>, <value4>,
    <field5>, <value5>
);

System.Uri fullURI = generator.GenerateFullUrl();

// to get the encoded URI, use the following code
fullURI.AbsoluteUri
Соответственно, на базе этого кода можно написать свой, который будет фильтровать по RecId и т.о. отображать текущие записи. Тут правда есть нюанс - в стародавние времена было модно сложные запросы вида %1.%2 == %3.%4 || %5.%6 == %7.%8 делать как Range по полю RecId, как по наиболее редко используемому полю в запросах. В этом случае фильтрация по RecID может работать некорректно. Поэтому я немного видоизменил код и попробовал фильтроваться по первичному ключу:

X++:
    public str generateFullURL()
    {
        str ret;
        FormRun formRun = element.args().caller();
        FormDataSource formDS = formRun.dataSource();
        if (formRun && formRun.isRootNavigable())
        {
            System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
            UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
            generator.MenuItemName = formRun.args().menuItemName();
            generator.MenuItemType = formRun.args().menuItemType();
            generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
            generator.Company = curExt();
            generator.EncryptRequestQuery = true;
            Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.RequestQueryParameterCollection requestQueryParameterCollection = generator.RequestQueryParameterCollection;
            DictTable dictTable = new DictTable(formDS.cursor().TableId);
            FieldId primaryKey = dictTable.primaryKeyField();
            if (!primaryKey)
            {
                primaryKey = fieldnum(Common, RecId);
            }
            requestQueryParameterCollection.AddRequestQueryParameter(formDS.name(), fieldId2Name(dictTable.id(), primaryKey), strfmt("%1", formDS.cursor().(primaryKey)));
            
            ret = generator.GenerateFullUrl().AbsoluteUri;
        }
        
        return ret;
    }
Осталась последняя деталь - этот код надо вывести на форму, которая открывается при нажатии на кнопку "Получить ссылку" на закладке Параметры
Нажмите на изображение для увеличения
Название: SNAG_Program-0021.png
Просмотров: 485
Размер:	19.7 Кб
ID:	11800

Здесь вызывается пункт меню FormRunGetLinkAction, который вызывает одноименную форму.
Теперь есть 2 варианта, как вставить наш код в эту форму (без оверлеинга):

А. Добавить Post-обработчик на метод run формы и в контрол Link записать наш текст. Это легкий способ, но он перезатирает стандартную функциональность
Б. Добавить Post-обработчик на метод run формы и добавить в рантайме динамически новый контрол.

Расширение (Extension) к самой форме создать не получится - установленные паттерны на ней не позволяют без ошибок компиляции добавить статический контрол. А менять паттерны Extension не разрешает.

Пойдем вторым путем (вариант Б). Не забудем вставить проверку существования контрола, на случай, если кнопку "Получить ссылку" попробуют нажать при уже открытой форме
X++:
    public void postRun()
    {
        this.showFullLink();
    }

    public void showFullLink()
    {
        if (element.args() && element.args().caller() && element.args().callerType() == UtilElementType::Form)
        {
            FormStringControl ctrlFullLink = this.ctrlFullLink();
            if (!ctrlFullLink)
            {
                ctrlFullLink = element.design().addControl(FormControlType::String, ctrlFullLinkName);
            }
            ctrlFullLink.allowEdit(false);
            ctrlFullLink.displayLengthMode(this.ctrlLink().displayLengthMode());
            ctrlFullLink.displayLength(this.ctrlLink().displayLength());
            ctrlFullLink.label("@SYS22569");
            ctrlFullLink.text(this.generateFullURL());
        }
    }
Теперь осталось самая малость - оформить все в полноценный класс

X++:
using Microsoft.Dynamics.AX.Framework.Utilities;
using Microsoft.Dynamics.@Client.ServerForm.Contexts;

class FormRunGetLinkActionHandler
{
    FormRun  element;
    private const str ctrlFullLinkName = "FullLink";
    
    
    public FormRun formRun (FormRun _formRun = element)
    {
        element = _formRun;
        return element;
    }

    public static FormRunGetLinkActionHandler construct(FormRun _formRun)
    {
        FormRunGetLinkActionHandler handler = new FormRunGetLinkActionHandler();
        handler.formRun(_formRun);
        return handler;
    }

    public str generateFullURL()
    {
        str ret;
        FormRun formRun = element.args().caller();
        FormDataSource formDS = formRun.dataSource();
        if (formRun && formRun.isRootNavigable())
        {
            System.Uri host = SessionContext::Get_Current().Get_RequestUrl();
            UrlHelper.UrlGenerator generator = new UrlHelper.UrlGenerator();
            generator.MenuItemName = formRun.args().menuItemName();
            generator.MenuItemType = formRun.args().menuItemType();
            generator.HostUrl = host.GetLeftPart(System.UriPartial::Path);
            generator.Company = curExt();
            generator.EncryptRequestQuery = true;
            Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.RequestQueryParameterCollection requestQueryParameterCollection = generator.RequestQueryParameterCollection;
            DictTable dictTable = new DictTable(formDS.cursor().TableId);
            FieldId primaryKey = dictTable.primaryKeyField();
            if (!primaryKey)
            {
                primaryKey = fieldnum(Common, RecId);
            }
            requestQueryParameterCollection.AddRequestQueryParameter(formDS.name(), fieldId2Name(dictTable.id(), primaryKey), strfmt("%1", formDS.cursor().(primaryKey)));
            
            ret = generator.GenerateFullUrl().AbsoluteUri;
        }
        
        return ret;
    }

    public void postRun()
    {
        this.showFullLink();
    }

    public void showFullLink()
    {
        if (element.args() && element.args().caller() && element.args().callerType() == UtilElementType::Form)
        {
            FormStringControl ctrlFullLink = this.ctrlFullLink();
            if (!ctrlFullLink)
            {
                ctrlFullLink = element.design().addControl(FormControlType::String, ctrlFullLinkName);
            }
            ctrlFullLink.allowEdit(false);
            ctrlFullLink.displayLengthMode(this.ctrlLink().displayLengthMode());
            ctrlFullLink.displayLength(this.ctrlLink().displayLength());
            ctrlFullLink.label("@SYS22569");
            ctrlFullLink.text(this.generateFullURL());
        }
    }

    public FormStringControl ctrlLink()
    {
        return element.design().controlName(formControlStr(FormRunGetLinkAction, Link));
    }

    public FormStringControl ctrlFullLink()
    {
        return element.design().controlName(ctrlFullLinkName);
    }

    [PostHandlerFor(formStr(FormRunGetLinkAction), formMethodStr(FormRunGetLinkAction, run))]
    public static void FormRunGetLinkAction_Post_run(XppPrePostArgs _args)
    {
        FormRunGetLinkActionHandler handler = FormRunGetLinkActionHandler::construct(_args.getThis());
        handler.postRun();
    }

}
На выходе мы получаем:
Нажмите на изображение для увеличения
Название: SNAG_Program-0022.png
Просмотров: 565
Размер:	109.0 Кб
ID:	11805
По нижней ссылке можно открыть одну отфильтрованную запись.

Ну и можно приложить модель (я все делал в отдельной модели) - файл axmodel (выгружался из PU10), выгруженный проект (axpp-файл) и решение (solution) в студии, чтобы пример было удобно открыть из студии
SysGetFullShareLink-VSUH.axmodel.rar
SysGetFullShareLink.axpp
SysGetFullShareLink_Project.rar
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 28.12.2017 в 13:49.
За это сообщение автора поблагодарили: mazzy (10), S.Kuskov (2), belugin (10), Logger (10), raz (10), Jorj (1), Ivanhoe (10), trud (7), gl00mie (10).
Старый 28.12.2017, 09:48   #2  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Круто. А есть ли защита от дурака и от умного? Явное отключение параметров, защита от перебора и т.п.? Или только права доступа?
__________________
Ivanhoe as is..
Старый 28.12.2017, 11:31   #3  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
В статье Create and use deep links написано:

Цитата:
Security
Site access
Access to the domain/client is controlled through the existing login and SSL mechanism.

Form access
Access to the form is controlled through the specified Menu Item, and the accompanying Menu Item security system. If a user navigates using a URL which contains a Menu Item that the user does not have access to, then the Menu Item security will prevent the form from opening. The user will receive message which says that they do not have the necessary permissions to open the form.

Data access
Access to data is controlled through the existing form-level queries. When a form is opened with a generated URL, the form will run its existing form-level queries, which restrict the user's access to data. The data context that is specified in the generated URL is consumed after these form-level queries are applied, and results only in further filtering of the data displayed to the user. In short, a generated URL can, at most, open a form and display all of the data that a form would display to the user based on the form-level queries. A generated URL cannot grant a user access to data that is otherwise inaccessible on the form when not using the generated URL.
Говоря по-русски:
Доступ к сайту обеспечивается протоколом HTTPS
Доступ к форме обеспечивается правами доступа к пункту меню, по которому генерится ссылка
Доступ к данным обеспечивается с помощью запросов на уровне формы. Т.е. пользователь не увидит данные, которые не может увидеть с помощью конкретной формы. Ну т.е. по сути фильтр накладывается на queryRun при уже существующем query
__________________
Возможно сделать все. Вопрос времени
Старый 28.12.2017, 11:46   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Ну т.е. по сути фильтр накладывается на queryRun при уже существующем query
Если это так, то наверно и этой проблемы не будет:

Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Соответственно, на базе этого кода можно написать свой, который будет фильтровать по RecId и т.о. отображать текущие записи. Тут правда есть нюанс - в стародавние времена было модно сложные запросы вида %1.%2 == %3.%4 || %5.%6 == %7.%8 делать как Range по полю RecId, как по наиболее редко используемому полю в запросах. В этом случае фильтрация по RecID может работать некорректно.
Старый 28.12.2017, 12:07   #5  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Если это так, то наверно и этой проблемы не будет:
Будет. Формирование запроса в моем случае производится до открытия формы. А есть некоторые формы (типа smmActivities), которые уже при открытии накладывают фильтр по RecId, т.е. уже после исполнения моего кода.
Учитывая, что это только один случай, то поэтому и хочется собрать статистику по прочим формам, т.к. естественно я не мог протестировать это на всех формах.

Пока по результатам тестирования выявлена только одно неудобство - кэширование. Т.е. при переходе между записями на форме - сама форма кэшируется (с т.з. программного кода - не закрывается) и в результате ссылка на вторую запись не формируется (не меняется после формирования по первой записи). Я пока думаю, как это можно побороть
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 28.12.2017 в 12:15.
Старый 28.12.2017, 13:37   #6  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Ошибка нашлась - в моем примере range на первичный ключ просто добавлялся, а не создавался заново. В результате повторного вызова генерации ссылки - система добавляла range, который естественно срабатывал по ИЛИ.
Код в исходном сообщении исправил, модель и проект перевыложил. Теперь ссылка генерится для каждой записи - своя.
Кстати, посмотреть результаты исполнения запроса можно после открытия формы, если открыть расширенный фильтр:
Нажмите на изображение для увеличения
Название: SNAG_Program-0023.png
Просмотров: 488
Размер:	101.9 Кб
ID:	11808
__________________
Возможно сделать все. Вопрос времени
Старый 28.12.2017, 13:49   #7  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
range на первичный ключ просто добавлялся, а не создавался заново.
Если создавать заново, то открывается широкое поле для просмотра запрещенного контента через отрицание.

например, фильтр !"" показывает ВСЕ непустое
__________________
полезное на axForum, github, vk, coub.
Старый 28.12.2017, 14:37   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
Если создавать заново, то открывается широкое поле для просмотра запрещенного контента через отрицание.

например, фильтр !"" показывает ВСЕ непустое
Не... Query на форме заново не создается. Он есть такой, какой есть и ничего запрещенного пользователь не увидит.
Это я уже через класс RequestQueryParameterCollection создаю новый Range и накладываю его на первичный ключ. Ошибка была в том, что при повторном вызов старый Range не удалялся, а новый создавался. В результате получалось так, что после перехода по ссылке - на форму накладывались 2 Range на одно поле, и они естественно работали по ИЛИ. Сейчас накладывается только 1 Range на первичный ключ

В общем - цель получения ссылки на конкретную запись - не ограничение прав пользователя, а отправки ему ссылки на конкретную запись со словами - "посмотри сюда".
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 28.12.2017 в 14:45.
За это сообщение автора поблагодарили: mazzy (2).
Старый 29.12.2017, 23:50   #9  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
А что с этим постом не так thwidmer: Deep links available in every form ?

И зачем "if (formRun" ? Он или есть или мы ловим null reference exception до if
X++:
        FormDataSource formDS = formRun.dataSource();
        if (formRun && formRun.isRootNavigable())
Старый 30.12.2017, 00:19   #10  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
И чтобы поддержать дух исследования хочется отметить что ссылки можно генерить и без аксапты, к примеру, из консольного приложения:
X++:
using Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper;
using System;

namespace URLGeneratorTest
{
    class Program
    {
        static void Main(string[] args)
        {
            UrlGenerator generator = new UrlGenerator();
            generator.MenuItemName = "VendTable";
            generator.MenuItemType = UrlGenerator.MenuItemTypes.Display;
            generator.HostUrl = @"https://yourvmname.cloudax.dynamics.com/";
            generator.Company = "usmf";

            var requestQueryParameterCollection = generator.RequestQueryParameterCollection;

            requestQueryParameterCollection.UpdateOrAddEntry("VendTable", "AccountNum", "1002");

            Console.WriteLine(generator.GenerateFullUrl().AbsoluteUri);
        }
    }
}
За это сообщение автора поблагодарили: sukhanchik (2), trud (7).
Старый 30.12.2017, 01:20   #11  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от skuull Посмотреть сообщение
А что с этим постом не так thwidmer: Deep links available in every form ?
Все так. Только вопрос - что мы хотим получить?
В данном примере делается расширение класса и мы получим изменим исходную ссылку. Т.е. это будет "вариант А".
Но с другой стороны - концептуально (на мой взгляд) сделать именно Extension как в том примере - более правильно.
Мой пример хорош как вариант кода "с одним объектом". Ну и мне всегда нравятся готовые примеры, которые можно скачать, влить к себе без лишних телодвижений и они сразу заработают.

Я не ломал стандартный функционал только по одной причине - если ссылка не будет работать (из-за внутренней логики какой-нибудь формы), то останется возможность использовать обычную (штатную) ссылку. Если бы я мог гарантировать работоспособность своего примера в 100% случаях всех форм, то можно было бы и заменить штатный функционал на измененный.

Ну и вообще моя позиция такова - что очень не хватает материалов на русском языке, даже если есть альтернатива на английском (не люблю буржуйский язык). Я не пользовался той статьей и она мне при поиске не попалась, поэтому привожу примеры на русском языке, даже если есть альтернативы на английском. Если источник примеров был на английском языке - то делаю ссылку. Если пример был написан самостоятельно - то ссылку не делаю.

Цитата:
Сообщение от skuull Посмотреть сообщение
И зачем "if (formRun" ? Он или есть или мы ловим null reference exception до if
X++:
        FormDataSource formDS = formRun.dataSource();
        if (formRun && formRun.isRootNavigable())
Код был взят с исходной формы FormRunGetLinkAction, плюс добавлено обновление датасорса. Замечание корректное, но ... null reference exception никогда не будет словлено, т.к. панель кнопок всегда привязана к исходной форме. Т.е. здесь просто лишняя проверка на formRun, которая в целом никому не мешает.
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 30.12.2017 в 01:33.
Старый 30.12.2017, 01:27   #12  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от skuull Посмотреть сообщение
И чтобы поддержать дух исследования хочется отметить что ссылки можно генерить и без аксапты, к примеру, из консольного приложения
Интересный пример, только ... в готовом виде невостребован. Т.е. этот код хорошо вставлять в другие приложения, причем четко понимать откуда брать параметры, какую форму открывать и по каким значениям фильтровать.

В целом, из C# можно вызывать любые классы X++, только ... вот граблей там хватает . Чтобы вот этот вот using написать - нужно Reference добавить, но не через GAC, а через dll-ку. И перебилдивать проект после обновления dll-ки
__________________
Возможно сделать все. Вопрос времени
Старый 30.12.2017, 02:16   #13  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Замечание корректное, но ... null reference exception никогда не будет словлено, т.к. панель кнопок всегда привязана к исходной форме. Т.е. здесь просто лишняя проверка на formRun, которая в целом никому не мешает.
Ну как никогда... Вы написали класс который принимает FormRun т.е. кто угодно может передать туда любой FormRun у которого может и не быть caller и напрямую вызвать generateFullURL, т.к. он публичный. Так же вы его назвали "полноценный". Это дает мне основание думать, что это не какой-то там примерчик, а целый класс, бери и используй

Выкладывая код на всеобщее обозрение надо быть готовым к тому что вам скажут про construct с параметрами который не best practice и про прочие мелочи
Старый 30.12.2017, 02:40   #14  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Интересный пример, только ... в готовом виде невостребован. Т.е. этот код хорошо вставлять в другие приложения, причем четко понимать откуда брать параметры, какую форму открывать и по каким значениям фильтровать.

В целом, из C# можно вызывать любые классы X++, только ... вот граблей там хватает . Чтобы вот этот вот using написать - нужно Reference добавить, но не через GAC, а через dll-ку. И перебилдивать проект после обновления dll-ки
Так и есть, в готовом виде не применим, но там из всяких CRMов или 3rd party уже синтегрированных где есть, к примеру, клиенты и заранее известна форма которую вы хотите открыть. Microsoft.Dynamics.AX.Framework.Utilities это и есть C# dll которая к X++ никакого отношения не имеет, в этом-то и был смысл примера и обновляться она будет только с Platform update'ом и то наверно очень редко.

Последний раз редактировалось skuull; 30.12.2017 в 02:54.
Старый 30.12.2017, 11:39   #15  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от skuull Посмотреть сообщение
Ну как никогда... Вы написали класс который принимает FormRun т.е. кто угодно может передать туда любой FormRun у которого может и не быть caller и напрямую вызвать generateFullURL, т.к. он публичный. Так же вы его назвали "полноценный". Это дает мне основание думать, что это не какой-то там примерчик, а целый класс, бери и используй
Все верно. Это целый класс - бери и используй. Но любые примеры всегда поставляются "как есть" под ответственность того, кто использует. Главная ценность этого класса - это быстрая возможность посмотреть, как он работает. Дальнейшая переработка кода оставляется на усмотрение того, кто будет его использовать. "Полноценность" примера состоит в его результирующей работоспособности, а не в готовности решения для использования в промышленной эксплуатации. Кто-то посчитает, что он готов, а кто-то нет. Это личная ответственность того, кто этот пример вставит себе в приложение

Теоретически возможно все и от дураков никогда не защитишься. Именно поэтому я и не стремлюсь это делать. Кому потребуется - тот навесит на пример дополнительные проверки и средства защиты.

Цитата:
Сообщение от skuull Посмотреть сообщение
Выкладывая код на всеобщее обозрение надо быть готовым к тому что вам скажут про construct с параметрами который не best practice и про прочие мелочи
У меня к моему великому счастью есть возможность не оглядываться на best practice и писать код так, как я считаю нужным. Этим примером никто не заставляет пользоваться
Выкладывая же код на данный общедоступный ресурс я исхожу из того, что пока больше никто аналогичных действий на этом ресурсе не делает, поэтому оставляю за собой право допускать несущественные (т.е. не ломающие работоспособность примера) ошибки и игнорировать сообщения про best pratice от тех, кто аналогичные примеры не выкладывает
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 30.12.2017 в 11:46.
За это сообщение автора поблагодарили: mazzy (2).
Старый 30.12.2017, 11:44   #16  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от skuull Посмотреть сообщение
обновляться она будет только с Platform update'ом и то наверно очень редко.
Вот в этой фразе есть логическая ошибка в слове "наверное". PU (особенно на ранних стадиях) сильно меняли систему. Конкретно эта dll может и не менялась, но ..."кто их знает".
Но в целом - это все понятно и в сторонних системах конечно будут использовать код для вызова логики D365 FO
__________________
Возможно сделать все. Вопрос времени
Теги
d365o, deep link, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Кликабельная URL-ссылка в отчёте tindomka DAX: Программирование 2 01.06.2017 23:06
dynaxtips: The URL Parameters Blog bot DAX Blogs 0 21.03.2017 03:13
Позиционирование на конкретную запись датасета Lucky13 DAX: Программирование 8 21.12.2005 19:26
Ошибка при импорте демоданных (Axapta 3.0 CIS SP1) KocDm DAX: Администрирование 2 11.08.2005 12:04
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:37.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.