Здравствуйте.

Есть проблема. Получаю данные из поля SearchData и преобразую их в JSON:

byte[] searchData = entity.GetBytesValue("SearchData");

string searchResult = Encoding.UTF8.GetString(searchData);

searchResult при этом приобретает такой вид:

{

    "className": "Terrasoft.FilterGroup",

    "items": {

        "a9fff128-8626-420b-a67f-b94b84b5042b": {

            "className": "Terrasoft.CompareFilter",

            "filterType": 1,

            "comparisonType": 3,

            "isEnabled": true,

            "trimDateTimeParameterToDate": false,

            "leftExpression": {

                "className": "Terrasoft.ColumnExpression",

                "expressionType": 0,

                "columnPath": "HasMobileApp"

            },

            "isAggregative": false,

            "key": "a9fff128-8626-420b-a67f-b94b84b5042b",

            "dataValueType": 12,

            "leftExpressionCaption": "Мобильное приложение",

            "rightExpression": {

                "className": "Terrasoft.ParameterExpression",

                "expressionType": 2,

                "parameter": {

                    "className": "Terrasoft.Parameter",

                    "dataValueType": 12,

                    "value": true

                }

            }

        }

    },

    "logicalOperation": 0,

    "isEnabled": true,

    "filterType": 6,

    "rootSchemaName": "Contact",

    "key": "FolderFilters"

}

Далее пытаюсь десериализовать в объект Terrasoft.UI.WebControls.Controls.DataSourceFilterCollection:

var jsonConverter = new DataSourceFiltersJsonConverter(UserConnection, UserConnection.EntitySchemaManager.GetInstanceByName("Contact")) { PreventRegisteringClientScript = true };

 DataSourceFilterCollection filters = JsonConvert.DeserializeObject(searchResult, jsonConverter);

                

И получаю ошибку: 

Newtonsoft.Json.JsonSerializationException: Additional text found in JSON string after finishing deserializing object.

   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)

   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)

Судя по ошибке, остались лишние поля, которых нет в объекте.

Возможно, проблема в jsonConverter. 

Коллеги, как этот JSON, превратить в EntitySchemaQueryFilterCollection.

 

 

 

 

Нравится

1 комментарий

Отвечу сам себе. Может кому пригодится:

Десерилизация:

Terrasoft.Nui.ServiceModel.DataContract.Filters filters = Terrasoft.Common.Json.Json.Deserialize<Terrasoft.Nui.ServiceModel.DataContract.Filters>(searchResult);

                

 IEntitySchemaQueryFilterItem esqFilters = filters.BuildEsqFilter("Contact", UserConnection);

var queryFilterCollection = esqFilters as EntitySchemaQueryFilterCollection;

                if (queryFilterCollection != null)

                {

                    contactESQ.Filters.LogicalOperation =  queryFilterCollection.LogicalOperation;

                    contactESQ.Filters.IsNot = queryFilterCollection.IsNot;

                    foreach (IEntitySchemaQueryFilterItem filter in queryFilterCollection)

                    {

                        contactESQ.Filters.Add(filter);

                    }

                }

Вопрос закрыт.

Показать все комментарии

Подскажите пожалуйста, в каком формате содержится фильтр в поле SearchData объекта ContactFolder.

При чтении данного поля получаю следующую информацию:



{"className":"Terrasoft.FilterGroup","items":{"65af680d-1eb1-43be-86ca-b8925182f2a2":{"className":"Terrasoft.CompareFilter","filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"className":"Terrasoft.ColumnExpression","expressionType":0,"columnPath":"Account.Name"},"isAggregative":false,"key":"65af680d-1eb1-43be-86ca-b8925182f2a2","dataValueType":1,"leftExpressionCaption":"Контрагент.Название","rightExpression":{"className":"Terrasoft.ParameterExpression","expressionType":2,"parameter":{"className":"Terrasoft.Parameter","dataValueType":1,"value":"Автомагазины"}}},"ebd926cc-b513-426c-a30b-212d7b38ca8c":{"className":"Terrasoft.CompareFilter","filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"className":"Terrasoft.ColumnExpression","expressionType":0,"columnPath":"Account.Name"},"isAggregative":false,"key":"ebd926cc-b513-426c-a30b-212d7b38ca8c","dataValueType":1,"leftExpressionCaption":"Контрагент.Название","rightExpression":{"className":"Terrasoft.ParameterExpression","expressionType":2,"parameter":{"className":"Terrasoft.Parameter","dataValueType":1,"value":"Автолиния"}}}},"logicalOperation":1,"isEnabled":true,"filterType":6,"rootSchemaName":"Contact","key":"FolderFilters"}

Но загрузка обратно этих текстовых данных в формате Base64 сбрасывает фильтр.

Помогите знающие, каким образом можно программно через OData генерировать фильтры. Заранее благодарю.

Нравится

12 комментариев

По моему предположению данное поле содержит сериализацию объекта. Если это так то, придётся попытаться действовать через другие инструменты...

Да, это сериализированный объект. Если удалось разобраться в его структуре, то нужно выяснить, на каком этапе у Вас в базу попало неверное значение: при построении этого JSON или при преобразовании текста в бинарные данные и записи в поле по OData Если есть прямой доступ к базе, попробуйте сначала менять это поле средствами SQL, записывая исправленное значение в колонку таблицы, преобразовывая в нужный тип.

А когда удастся добиться работоспособности, то смотрите, что не так при передаче из веб-сервиса. Также можно запустить Fiddler, проделать изменение и сохранение фильтра в браузере и посмотреть, какой HTTP-запрос при этом уйдёт на сервер.

Изначально я настроил руками фильтр, далее этот фильтр я считал через OData в виде текста JSON. Далее заношу ровно тот же текст JSON упакованный в двоичные данные Base64. Если просто положить текст, то программа не открывает редактирование фильтра. А если в двоичных данных, то открывает пустой фильтр, как будто фильтра никогда там и не было...

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

Зверев Александр,

Попробую что нибудь придумать, хотя со стороны 1С это сделать крайне проблематично...

Для начала попробуйте разобраться через базу. Если ещё и 1С привлекать, причину неверного фильтра искать будет ещё сложнее: слишком много мест, где что-то могло пойти не так.

Зверев Александр,

У меня только в облаке. Скорее всего фильтр записан в кодировке ANSI, а 1С текст держит в UTF-8 кодировке... Я попробую разобраться считав двоичные данные или работая через поток...

Для эксперимента ещё можно отправлять HTTP-запросы прямо из Fiddler.

Учту, хотя в 1С гораздо проще и быстрее проверять идеи. Все инструменты работы с данными там есть...

Зверев Александр,

Спасибо за моральную поддержку. Разобрался. В общем в поле содержится просто JSON текст в ANSI формате. Нужно немного доработать, а так фильтр работает...

Зверев Александр,

Подскажи пожалуйста в какой кодировке сереализуется текст, если данная информация у вас есть?.. Уже испробовал кучу кодировок и без толку, только кроказябры изменяются в значении фильтра. Либо фильтр перестаёт открываться на кодировках UTF-7...UTF-32...

UTF-7, UTF-8, UTF-16, UTF-32, OEM, ANSI, US-ASCII, CP866, windows-1251 по 1254, KOI8R, KOI8U...

Видимо, преобразование в бинарные данные делается стандартными средствами SQL-сервера. Если написать:

SELECT [SearchData]
, cast ([SearchData] as varchar(max))
, cast(cast ([SearchData] as varchar(max)) as varbinary(max))
FROM [AccountFolder]

Получим в первой колонке бинарные данные, во второй — текст JSON, а в третьей — те же данные, что в первой. При этом во второй колонке кириллица выводится как «ÐžÑ‚Ñ€Ð°ÑÐ»ÑŒ Консалтинг». Если вставить в «Декодер» , он выдаст: «Отра�ль Кон�алтинг CP1252->UTF-8».

Показать все комментарии