|
не могу прочитать json :( | ☑ | ||
---|---|---|---|---|
0
I_learn_1c
13.05.20
✎
23:01
|
Доброй ночи,
Помогите пожалуйста..... HTTP ответ нужно прочитать в структуру. Код состояния 200, все норм. На ПрочитатьJSON(ЧтениеJSON) Ошибка при вызове метода контекста (ПрочитатьJSON). Что не так не пойму... перечитала синтакс помощник раз 10 уже, даже если пустую строку "{}" дать, то ошибка контекста. Вызывается в общем модуле с галками клиент, сервер, внешнее соединение. Пишу: HTTPОтвет = Соединение.ОтправитьДляОбработки(ЗапросHTTP); СтрокаJSON = HTTPОтвет.ПолучитьТелоКакСтроку(); //Разбираем ответ ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(СтрокаJSON); Попытка РезультатСоответствие = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("1"); КонецПопытки; |
|||
1
I_learn_1c
13.05.20
✎
23:03
|
(0) если пробую в том же месте простенький пример (ниже), то работает. а как прочитать то что возвращает сервер в СтрокаJSON ... не пойму. там много, не стала вставлять сюда
В СтрJSON получается { "server": 10234, "user": 3745, "hash": "8263ad83ce" } Пример кода ДанныеСтр = Новый Структура("server,user,hash", 10234, 3745, "8263ad83ce"); мЗапись = Новый ЗаписьJSON; мЗапись.УстановитьСтроку(); ЗаписатьJSON(мЗапись, ДанныеСтр); СтрJSON = мЗапись.Закрыть(); тЧтение = Новый ЧтениеJSON; тЧтение.УстановитьСтроку(СтрJSON); Структура = ПрочитатьJSON(тЧтение); |
|||
2
palsergeich
13.05.20
✎
23:10
|
(1) проверь то что возвращает сервер валидатором/эдитором, может там не каннонический json.
Например для bulk операций в некоторых системах приходит не json а куча json разделенных символами ПС https://jsoneditoronline.org/ я этим пользуюсь |
|||
3
рикардо милос
13.05.20
✎
23:15
|
Параметры:
<ЧтениеJSON> (обязательный) Тип: ЧтениеJSON. Объект чтения JSON. <ПрочитатьВСоответствие> (необязательный) Тип: Булево. Если установлено Истина, чтение объекта JSON будет выполнено в Соответствие. Если установлено Ложь, объекты будут считываться в объект типа Структура. вот этот параметр ПрочитатьВСоответствие=Истина |
|||
4
palsergeich
13.05.20
✎
23:22
|
(3) чтение в соответствие выручки только тогда когда ключи не могут быть ключами структуры (точка в имени) свойства наприиер и ещё какой то экзотический случай, но там другая ошибка вроде, не про контекст.
|
|||
5
palsergeich
13.05.20
✎
23:23
|
Я бы таки начал с проверки json на валидность и отсутствие недопустимых символов
|
|||
6
Asmody
13.05.20
✎
23:45
|
И что показывает отладчик после
СтрокаJSON = HTTPОтвет.ПолучитьТелоКакСтроку(); ? |
|||
7
Asmody
13.05.20
✎
23:46
|
(5) я бы таки начал с проверки ответа сервера
|
|||
9
I_learn_1c
14.05.20
✎
00:03
|
(2) https://jsoneditoronline.org/ дерево строит, вроде нормально все
|
|||
10
Turku
14.05.20
✎
00:08
|
Параметры:
<ЧтениеJSON> (обязательный) Тип: ЧтениеJSON. Объект чтения JSON. <ПрочитатьВСоответствие> (необязательный) Тип: Булево. Если установлено Истина, чтение объекта JSON будет выполнено в Соответствие. Если установлено Ложь, объекты будут считываться в объект типа Структура. Примечание. При десериализации объектов JSON в структуру необходимо помнить о требованиях к ключам структуры. Если при десериализации объекта будет найдено имя свойства, недопустимое для ключа структуры, то будет вызвано исключение. Значение по умолчанию: Ложь. Надо поправить на РезультатСоответствие = ПрочитатьJSON(ЧтениеJSON,Истина); |
|||
11
I_learn_1c
14.05.20
✎
00:11
|
(10) не помогает, все равно ошибка про контекст
|
|||
12
NecroDog
14.05.20
✎
00:15
|
Полное описание ошибки есть? Ошибка метода контекста обычно сопровождается каким-нибудь комментарием.
|
|||
13
I_learn_1c
14.05.20
✎
00:23
|
(12) неа... все что есть↓
Уходит в исключение вот тут, в исключении ИнформацияОбОшибке() или ОписаниеОшибки() возвращают "", если отладкой открыть ПрочитатьJSON(ЧтениеJSON, Истина), то видна ошибка, и в РезультатСоответствие будет неопределено в итоге Попытка РезультатСоответствие = ПрочитатьJSON(ЧтениеJSON, Истина); Исключение Сообщить("1"); КонецПопытки; https://yadi.sk/i/jMGpj7l-Mm8SCg |
|||
14
NecroDog
14.05.20
✎
00:27
|
Вызовите метод ПрочитатьJSON вне попытки или в Сообщить() передайте ОписаниеОшибки(). В отладке полное описание ошибки не увидеть.
|
|||
15
I_learn_1c
14.05.20
✎
00:33
|
(14) ОписаниеОшибки при попадании в исключение в предприятии вывело
{ОбщийМодуль.D3_ИнтеграцияБитрикс.Модуль(44)}: Ошибка при вызове метода контекста (ПрочитатьJSON): Недопустимое состояние потока записи JSON |
|||
16
I_learn_1c
14.05.20
✎
00:36
|
(15)уффф... это парсить вручную выходит нужно такое?
|
|||
17
Garykom
гуру
14.05.20
✎
00:37
|
Пиши HTTPОтвет в файл и читай из файла.
|
|||
18
Garykom
гуру
14.05.20
✎
00:39
|
(17)+ Два варианта или в строку все не влезло или не валидный json с точки зрения 1С.
Попробуй как в файлу сохранишь поизвращаться с ним, убрать разные левости (типа "\/" и прочего) и выяснить на чем падает. |
|||
19
Garykom
гуру
14.05.20
✎
00:45
|
(17)+ Кодировку проверить, может есть некорректные символы на которые валидаторы плюют а 1С падает
|
|||
20
I_learn_1c
14.05.20
✎
00:46
|
(17) что-то туплю.. а как записать HTTPОтвет в файл?
СтрокаJSON = HTTPОтвет.ПолучитьТелоКакСтроку(); ИмяВремФайла = ПолучитьИмяВременногоФайла("json"); мЗапись = Новый ЗаписьJSON; мЗапись.ОткрытьФайл(ИмяВремФайла); //?????? что тут мЗапись.Закрыть(); |
|||
21
Garykom
гуру
14.05.20
✎
00:56
|
(20)
ФайлРезультат = ПолучитьИмяВременногоФайла(); затем в СП HTTPСоединение.ОтправитьДляОбработки смотри параметры |
|||
22
Garykom
гуру
14.05.20
✎
00:59
|
ФайлРезультат = ПолучитьИмяВременногоФайла();
HTTPОтвет = Соединение.ОтправитьДляОбработки(ЗапросHTTP, ФайлРезультат); |
|||
23
I_learn_1c
14.05.20
✎
01:04
|
(21) все равно валится с Недопустимое состояние потока записи JSON... видимо в строке серьезные косяки для 1с
ИмяВремФайла = ПолучитьИмяВременногоФайла(); HTTPОтвет = Соединение.ОтправитьДляОбработки(ЗапросHTTP,ИмяВремФайла); //Разбираем ответ тЧтение = Новый ЧтениеJSON; тЧтение.ОткрытьФайл(ИмяВремФайла); Попытка РезультатСоответствие = ПрочитатьJSON(тЧтение, Истина); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; |
|||
24
Garykom
гуру
14.05.20
✎
01:08
|
(23) Выложи этот ИмяВремФайла куда то и сам его проверь глазками.
|
|||
25
Garykom
гуру
14.05.20
✎
01:08
|
(24) *сама
|
|||
26
Garykom
гуру
14.05.20
✎
01:11
|
||||
27
lodger
14.05.20
✎
01:14
|
(23) это не косяки серьезные, а вариативность JSON не позволяет парсить всё что угодно в полностью автоматическом режиме
читайте https://wonderland.v8.1c.ru/blog/sredstva-raboty-s-json/ хотя бы заголовок "Сериализация типа Дата". а еще есть педали "Функции преобразования и восстановления". |
|||
28
Garykom
гуру
14.05.20
✎
01:14
|
"link":"\/company\/personal\/user\/50\/",
Вот тут лишнее экранирование, только обратный слеш обязательно "\\" - надо "/" - можно без экранирование через "\" |
|||
29
I_learn_1c
14.05.20
✎
01:26
|
(28) а насчет дат заморачиваться или их должно бы прочитать?
|
|||
30
Asmody
14.05.20
✎
01:27
|
(8) там написано было почему закрыли
|
|||
31
Garykom
гуру
14.05.20
✎
01:28
|
(29) Возьми эти строковые даты, вставь в пустой json и попробуй парсятся ли в 1С.
И аналогично со всеми подозрительными |
|||
32
vde69
14.05.20
✎
07:58
|
сейчас много работаю с json но не в 1с, основных причин сабжа всего 3
1. не сериализуемый объект 2. не поддерживаемый уровень вложености 3. запрещенные или не поддерживаемые символы искать ошибку надо так 1. общая проверка (помогает найти нестандартные символы и объекты) делаем двойное преобразование в каком онлайн сервисе декоде+обратное кодирование, потом сравниваем строки 2. дробим на куски по уровням вложености и пробуем загрузить в 1с кусочки |
|||
33
Василий Алибабаевич
14.05.20
✎
08:15
|
(32) Другое дело. Все сразу стало понятно...)))
Обычно в дешевых американских фильмах вместо вот этого : "1. не сериализуемый объект 2. не поддерживаемый уровень вложености 3. запрещенные или не поддерживаемые символы" говорят - "что-то пошло не так". Результат и одного и другого одинаков. |
|||
34
I_learn_1c
14.05.20
✎
09:44
|
(28) какая-то странная фигня происходит..
в общем если поставить одну точку останова на Сообщить("5 все ок") или Сообщить("5") то до нее доходит без ошибок, читает в соответствие, и ссылки со слешами верно читает, только дата в виде строки в итоге "2020-05-14T09:34:23+03:00" в структуру не читает, т.к. есть такое вот в строке "..."edit.originator":true,..." ну а в структуре нельзя точку в заголовок, ок, допустим, пусть соответствие. но если поставить точку останова где-то до попытки и идти пошагово, то вываливается на ПрочитатьJSON в исключение... Попытка РезультатСоответствие = ПрочитатьJSON(тЧтение,Истина); Сообщить("5 все ок"); Сообщить("5"); Исключение Сообщить("1 "+ОписаниеОшибки()); КонецПопытки; |
|||
35
I_learn_1c
14.05.20
✎
09:46
|
(34) с ошибкой "недопустимое состояние потока записи json"
|
|||
36
dezss
14.05.20
✎
09:55
|
Сделай уже Сообщить(СтрокаJSON)
И кидай что получилось сюда. Увидим что не так. |
|||
37
Мимохожий Однако
14.05.20
✎
09:56
|
Убери из файла ответа /
|
|||
38
RomanYS
14.05.20
✎
09:57
|
(34) Убери ПрочитатьJSON из табло отладчика. Ошибка вероятно при повторном вызове.
|
|||
39
trad
14.05.20
✎
09:57
|
(36) нет, это слишком просто
|
|||
40
FormatC
14.05.20
✎
09:58
|
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); // удалим открывающий символ структуры(массива) НомерЗначения = 0; Пока ТекстJSON <> "" Цикл ПервыйСимвол = Лев(ТекстJSON, 1); Если ПервыйСимвол = "{" Тогда // вложенная структура Значение = Новый Структура; ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура"); Если ТипДанных = "Структура" Тогда Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение); НомерЗначения = НомерЗначения + 1; ИначеЕсли ТипДанных = "Массив" Тогда Результат.Добавить(Значение); КонецЕсли; ИначеЕсли ПервыйСимвол = "[" Тогда // вложенный массив Значение = Новый Массив; ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив"); Если ТипДанных = "Структура" Тогда Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение); НомерЗначения = НомерЗначения + 1; Иначе Результат.Добавить(Значение); КонецЕсли; ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда // структура закончилась ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); Если Лев(ТекстJSON, 1) = "," Тогда ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); КонецЕсли; Возврат; ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда // массив закончился ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); Если Лев(ТекстJSON, 1) = "," Тогда ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); КонецЕсли; Возврат; Иначе Если ТипДанных = "Структура" Тогда //ПервыйКавычка = Ложь; //Если Лев(ТекстJSON, 1) = """" Тогда // ПервыйКавычка = Истина; //КонецЕсли; Поз = Найти(ТекстJSON, ":"); Если Поз = 0 Тогда // неверный формат, прервемся Прервать; КонецЕсли; //ПредпоследнийКавычка = Ложь; //Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда // ПредпоследнийКавычка = Истина; //КонецЕсли; ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз - 1)); ИмяЗначения = СтрЗаменить(ИмяЗначения, """", ""); ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1)); Если Лев(ТекстJSON, 1) = "{" Тогда // значение является структурой Значение = Новый Структура; ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура"); ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда // значение является массивом Значение = Новый Массив; ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив"); Иначе // обычное значение ПервыйКавычка = Ложь; ПредпоследнийКавычка = Ложь; Поз = 0; Для Сч = 1 По СтрДлина(ТекстJSON) Цикл Символ = Сред(ТекстJSON, Сч, 1); Если Символ = """" Тогда Если ПервыйКавычка Тогда ПредпоследнийКавычка = Истина; Иначе ПервыйКавычка = Истина; КонецЕсли; КонецЕсли; Если (Символ = "," И ((ПервыйКавычка И ПредпоследнийКавычка) Или (Не ПервыйКавычка И Не ПредпоследнийКавычка))) ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда Поз = Сч; Прервать; КонецЕсли; КонецЦикла; //ПредпоследнийКавычка = Ложь; //Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда // ПредпоследнийКавычка = Истина; //КонецЕсли; Если Поз = 0 Тогда Значение = ТекстJSON; ТекстJSON = ""; Иначе Значение = Лев(ТекстJSON, Поз - 1); Значение = СтрЗаменить(Значение, """", ""); ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0))); КонецЕсли; Значение = СокрЛП(Значение); КонецЕсли; Попытка Результат.Вставить(ИмяЗначения, Значение); Исключение Конецпопытки; ИначеЕсли ТипДанных = "Массив" Тогда // обычное значение Поз = 0; Для Сч = 1 По СтрДлина(ТекстJSON) Цикл Символ = Сред(ТекстJSON, Сч, 1); Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда Поз = Сч; Прервать; КонецЕсли; КонецЦикла; //ПредпоследнийКавычка = Ложь; //Если Сред(ТекстJSON, Поз - 1, 1) = """" Тогда // ПредпоследнийКавычка = Истина; //КонецЕсли; Если Поз = 0 Тогда Значение = ТекстJSON; ТекстJSON = ""; Иначе Значение = Лев(ТекстJSON, Поз - 1); Значение = СтрЗаменить(Значение, """", ""); ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0))); КонецЕсли; Значение = СокрЛП(Значение); Результат.Добавить(Значение); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт Результат = Новый Структура; ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """"); // заменим последовательность \" на " ТекстJSON = СтрЗаменить(ТекстJSON, """", ""); // а теперь удалим все кавычки Если Лев(ТекстJSON, 1) = "{" Тогда // начало структуры ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура"); ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда // начало массива МассивДанных = Новый Массив; ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив"); Результат.Вставить("Значение", МассивДанных); КонецЕсли; Возврат Результат; КонецФункции |
|||
41
dezss
14.05.20
✎
09:59
|
(38) Хм..а это идея...вот даже не думал, что кто-то догадается такое делать.
|
|||
42
I_learn_1c
14.05.20
✎
09:59
|
(36) там большая строка, прошлую ветку закрыли, за то что вставила
|
|||
43
arsik
гуру
14.05.20
✎
10:01
|
(42) Сюда закинь https://pastebin.com/
|
|||
44
trad
14.05.20
✎
10:01
|
(42) облако
|
|||
45
I_learn_1c
14.05.20
✎
10:05
|
(38) похоже работает... если не ставить точку на самой строке РезультатСоответствие = ПрочитатьJSON(тЧтение,Истина);
т.е. я потратила день, на то, чтобы это пытаться прочитать без ошибки.. а нужно было ставить в другом месте точку останова.. |
|||
46
I_learn_1c
14.05.20
✎
10:08
|
(45) точнее точку поставить можно, в табло не надо выводить... спасибо большое
|
|||
47
RomanYS
14.05.20
✎
10:23
|
(46) Именно: не надо в табло вызывать методы, которые изменяют контекст
|
|||
48
dezss
14.05.20
✎
10:24
|
Хм...а фотки в качестве награды не будет?)))
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |