Многие при работе с корпоративным порталом (Enterprise Portal) в Microsoft Axapta сталкиваются с ошибкой 'Недопустимый диапазон'. В этом совете рассказано как бороться с этой ошибкой.

Ошибка 'Недопустимый диапазон.'На скриншоте справа показана эта ошибка. Появляется она, как правило, если в коде записи, которую должен показать корпоративный портал, содержатся русские буквы (или другие неASCII символы).

В чем причина?

Любое веб-приложение всю информацию может передать только в адресной строке. Причина ошибки кроется в том, как корпоративный портал передает информацию о записи, которую надо отобразить.

Если свойствах таблицы указано, что индекс по RecID не нужен, то Аксапта берет первый попавшийся уникальный индекс и составляет адрес записи следующим образом WKEY=[fieldId1,fieldValue1][fieldId2,fieldValue2]... Где fieldId1, fieldId2 и т.д. - поля, входящие в уникальный индекс отображаемой таблицы. А fieldValue1, fieldValue2 и т.д. - значения этих полей соответственно.

Если в таблице есть индекс по RecId, то в адресной строке в параметре WKEY передается RecID. На картинке ниже recid = 8520336. А код поля RecID = 65534 (-1).

Параметр WKEY передает информацию о записи, которая должна быть отображена

Обратите внимание: если в таблице нет уникального индекса, то Аксапта берет первый попавшийся индекс и к списку полей добавляет recId. Смотрите метод Global::record2DynaKey() для того, чтобы узнать детали.

При создании параметра WKEY для таблиц без индекса RecID и возникает проблема. Дело в том, что символы кирилицы в адресной строке могут быть закодированы при помощи "безопасного" набора символов из ASCII-таблицы.

Аксапта использует метод iisServer.htmlEncode() для кодирования в безопасный набор символов. Этот метод находится в ядре и недоступен программисту. В этом методе и происходит ошибка. Вместо кодирования в %-стиле, метод кодирует в стиле html-кода. Например, буква Г кодируется как Г.

Взглянем поподробнее на адресную строку страницы, в которой возникла ошибка.

Адресная строка страницы с ошибкой.

Та-да-а-ам! Вот оно!

Во-первых, правильно закодирован только первый символ (обратите внимание, у второго и следующих не хватает #). А во-вторых, и это самое главное, символ & является разделителем между параметрами в адресной строке. А это значит, параметр WKEY получит значение "[1:", когда IIS получит и разберет строку. Именно поэтому Аксапта и ругается на недопустимый диапазон.

 

Что делать?

Есть два способа. И оба способа требуют средств разработки.

Способ 1

В таблицах, по которым ругается корпоративный портал, создайте индекс по recId. Для этого установите у свойства таблицы CreateRecIdIndex значение Yes.

Код таблицы можно узнать, если посмотреть в адресной строке на параметр WTID (в нашем примере это таблица с номером 103) и воспользоваться небольшим Job'ом:

static void mazTableName(Args _args)
{
;
   info(new dicttable(103).name());
}

Спасибо Андрею Васько и Вадиму Гончаренко за предложенный способ.

 

Способ 2

Из соображений производительности не всегда желательно создавать новый индекс. Кроме того, бывают случаи, когда создание индекса по RecId просто невозможно. В таких случаях можно подправить код, где выполняется кодирование адреса. В методе WebLink::url найдите строчку, в которой вызывается iisServer.htmlEncode.

Метод webLink::url

Либо вообще уберите вызов этого метода, либо замените на вызов своего кодировщика. Для целей тестирования вполне достаточно просто убрать кодирование в безопасный набор. В большинстве случаев, пользователи не используют спецсимволы (<, ", &, >), а современные браузеры нормально работают с Unicode-символами.

Однако, в боевых условиях отсутствие кодировщика означает дыру в безопасности. Конечно, вставить опасный код в 10-20 символов кода очень сложно. Однако не завбывайте, что бывают таблицы, где в уникальный индекс входит наименование. А туда уже вполне вставить очень даже зловредный код. Поэтому в боевых условиях кодирование в безопаснй набор обязательно.

Буду рад Вашим замечаниям и предложениям.
mazzy@mazzy.ru, Мазуркин Сергей