При интеграции 1С с внешними системами через протокол OData часто возникают сложности при передаче строковых значений, содержащих «небезопасные» символы. Особенно остро эта проблема встает при работе со справочниками, хранящими коды маркировки DataMatrix. Такие коды включают в себя служебные символы (01), (21), а также знаки +, &, ! и, что самое критичное, апострофы ', которые используются в языке запросов OData для ограничения строковых литералов.
Когда вы формируете URL запроса к OData, парсер ожидает, что строковый параметр в фильтре будет заключен в одинарные кавычки. Если внутри самого кода маркировки встречается такой же символ (например, в части кода Un+trgcG'GtRq), OData-парсер считает, что на этом символе строка завершилась. Это приводит либо к синтаксической ошибке, либо к обрезанию данных. Кроме того, символы вроде & или + могут быть ошибочно интерпретированы сервером как разделители параметров URL.
Согласно спецификации протокола OData, если внутри строкового значения должна присутствовать одинарная кавычка, ее необходимо экранировать путем дублирования. Это стандартное правило для многих SQL-подобных языков. Вместо одного символа ' в строке, которую вы передаете в фильтр, необходимо поставить два подряд ''.
Рассмотрим пример. Если ваш код маркировки выглядит как (21)Un'GtRq, то в строке фильтра он должен быть представлен как (21)Un''GtRq. Без этого преобразования OData не сможет корректно распознать конец строки.
После того как вы обработали внутренние кавычки, необходимо закодировать весь URL или его часть с параметрами. Это критически важный этап, так как символы, имеющие специальное значение в протоколе HTTP (такие как пробелы, скобки, плюсы), должны быть представлены в виде %HH.
В 1С для этих целей удобно использовать функцию КодироватьСтроку(). Важно понимать последовательность действий:
' на ''.ЗначениеШтрихкода eq '(01)04610063990116(21)Un''GtRq'.URL.Посмотрим на примере 1С, как это реализовать:
// Пример подготовки строки фильтра
ИсходныйКод = "(01)04610063990116(21)Un'GtRq";
ЭкранированныйКод = СтрЗаменить(ИсходныйКод, "'", "''");
СтрокаФильтра = "ЗначениеШтрихкода eq '" + ЭкранированныйКод + "'";
// Кодируем для URL
ЗакодированнаяСтрока = КодироватьСтроку(СтрокаФильтра, СпособКодированияСтроки.КодировкаURL);
// Полученный результат можно подставлять после $filter=
Коды DataMatrix нередко содержат непечатаемые символы, такие как FNC1. При передаче таких данных через OData возможны конфликты на уровне веб-сервера. Если вы столкнулись с тем, что даже после экранирования кавычек код не находится, обратитесь к официальным рекомендациям системы маркировки «Честный ЗНАК». Существуют алгоритмы преобразования (экранирования) спецсимволов GS1, при которых непечатаемые символы заменяются на их текстовые аналоги.
Если проект позволяет, рассмотрите переход на использование собственных HTTP-сервисов вместо стандартного OData. Это позволит вам:
POST-запроса в формате JSON.URI, так как данные будут передаваться в «сыром» виде.Для успешной работы с OData всегда помните про двухуровневую обработку: сначала логическое экранирование внутри синтаксиса (дублирование апострофов), затем физическое кодирование URL для безопасной передачи по протоколу HTTP. Если вы четко следуете этим двум шагам, ваш фильтр по штрихкоду будет отрабатывать корректно и без ошибок синтаксического разбора.