Получаю записи о счетах по ссылке:



https:///0/ServiceModel/EntityDataService.svc/InvoiceCollection



В ответ приходит xml содержащий ссылки на xml с различной информацией. Меня интересует информация о продуктах счета. Для этого перехожу по ссылке:



https:///0/ServiceModel/EntityDataService.svc/InvoiceCollection(guid'00000000-0000-0000-0000-000000000000')/InvoiceProductCollectionByInvoice



Но в ответ получаю xml с ошибкой: Method 'SelectMany' not supported



Насколько я понял, необходимо добавить фильтр в ссылку, но не понимаю как это сделать так, чтобы получить все записи о продуктах в счете.



Так же интересует как получить информацию о кол-ве продуктов в счете.

Нравится

2 комментария
Лучший ответ

Добрый день!

Про фильтрацию:

https://<адрес>/0/ServiceModel/EntityDataService.svc/InvoiceProductCollection?$filter=Invoice/Id eq guid'7e78ff39-ded1-416d-995a-71cef69387e8'

 

Добрый день!

Про фильтрацию:

https://<адрес>/0/ServiceModel/EntityDataService.svc/InvoiceProductCollection?$filter=Invoice/Id eq guid'7e78ff39-ded1-416d-995a-71cef69387e8'

 

Сидоров Александр В.,

Большое спасибо, вроде бы работает!)

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

Добрый день, Коллеги!

У нас 1с через Odata передает данные о заказе, включая поле Дата (Date)

На сервере часовой пояс киевский, у супервизора тоже киевский, в bpm в системной настройке киевский.

1-ка забирает дату и нормально себе записывает, но когда передает обратно заказ при изменении, дата записывается в бпм и пользователь видит дату + 3 часа сверху.

Знаю, что время в bpm хранится в UTC и когда из 1с приходит дата она записывается в это поле и пользователь видет + 3 часа.

Например создал заказ в бпм. Дата 9 утра. (если sql запрос сделать в базу) там 6 утра. Все ок, пользователь видит 9. Ушло в 1с, там заказ провели и возвращают в бпм. Уходит из 1с тоже 9 утра. Пришел в бпм, смотрим запросом в базу, там стало 9 утра, а пользователь видит 12 часов уже, т.е + 3 часа.

Как правильно передать запрос. Пробовали так:

{

    "AccountId": "590eb789-2b6d-4257-838f-917003ffce43",

    "CHOurCompanyId": "3d5d64dd-450f-4d70-a722-ee95caa2a5b3",

    "StatusId": "40de86ee-274d-4098-9b92-9ebdcf83d4fc",

    "CHVATTop": "false",

    "Date": "2019-06-04T12:05:12+TZ",

    "Number": "УТХ00013754",

    "Amount": "391",

    "OpId1C": "41d319dd-86a4-11e9-8102-e36315b16de3"

выдает ошибку - Cannot convert a primitive value to the expected type 'Edm.DateTime'. See the inner exception for more details.



Подскажите, как правильно сделать, может код на поле навешать в бпм

Нравится

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

«+TZ» — это не прямо так нужно писать, а указать нужный пояс. Например,«2018-01-31T08:24:49+03:00». Подробнее по работе с датой см. в этой теме.

Ок, сделали так зашло правильно, а когда мы на зимнее время перейдем, время будет правильно по прежнему?

Википедия гласит:

Следует помнить, что время по UTC не переводится ни зимой, ни летом. Поэтому для тех мест, где есть переход на летнее время, меняется смещение относительно UTC.

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

т.е в запрос при переходе на зимнее надо менять с +03:00 на +02:00?

если да, то как можно настроить передачу черед одата, чтобы время автоматически всегда правильно отображалось?

Можно на стороне 1С перед передачей даты вычислять текущее значение смещения.

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

При создании лида по OData пришит ответ 412 "Не совместимы тип". Доступ на обьект дан, при запросы на получения данных но ID лида ответ приходит

Изображение удалено.

 

Нравится

5 комментариев
Лучший ответ

Александр Тыра,

Если доступна база и профилировщик, посмотрите, какие запросы уходят в базу. Потому что на первый взгляд у вас все написано верно

Добрый день!

Убедитесь, что ожидается запрос в Json. Т.е. в заголовках есть: Content-Type:application/json;odata=verbose

Сидоров Александр В., отправляю и принимаю json, ответ такой же - 415

Александр Тыра,

Попробуйте именно 

Content-Type:application/json;odata=verbose

Сидоров Александр В., Прошло, формат приляно, но теперь ругается на ключ в таблице "Города". При этом Id верный, скопировал с самой базы

Александр Тыра,

Если доступна база и профилировщик, посмотрите, какие запросы уходят в базу. Потому что на первый взгляд у вас все написано верно

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

Доброго дня,

столкнулся с проблемой, прошу вашей помощи.

при попытке обновлении guid("UsrRegistrationStatusId") с помощью odata используя json формат полезной нагрузки получаю ошибку 

"message": "Cannot convert a primitive value to the expected type 'Edm.Guid'. See the inner exception for more details."
"message": "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."

 привожу пример

http метод put,

передаваемый json  

{

"UsrRegistrationStatusId":"a9d44061-de29-4578-9df6-d2f226573a06",

"UsrTitle":"myvalue",

"UsrFirstName":"myvalue",

"UsrLastName":"myvalue",

"UsrPreferredEmail":"myvalue@mm.mm",

"UsrDateOfBirth":"2019-04-18T11:14:26.697Z",

"UsrOccupation":"myvalue",

"UsrJobTitle":"myvalue",

"UsrCompanyPersonal":"myvalue",

"UsrComment":"myvalue",

"UsrModifiedOn":"2019-04-18T11:14:26.697Z",

"UsrPassportNumber":"myvalue",

"UsrContactNumber":"myvalue",

"UsrDateOfExpiry":"2019-04-18T11:14:26.697Z",

"UsrNationality":"myvalue",

"UsrGuestTypeId":"myvalue",

"UsrMainGuestId":"myvalue",

"UsrIsAccompanyingPerson":"myvalue",

"UsrFlightsModifiedOn":"2019-04-18T11:14:26.697Z"

}

Возможно ли сформировать поля в json  с определенным типом например Edm.Guid ? Было бы круто если покажите пример с описанием типа данных.

Спасибо за внимание!

 

 

Нравится

11 комментариев
Лучший ответ

Привидите полный код формирования запроса с установкой всех служебных заголовков и обратите внимание на примеры для c# 

Представьте Id  Guid в вашем Json как

guid'9d44061-de29-4578-9df6-d2f226573a06'

Спасибо за ответ!

но не помогло  ошибка таже,

urn запроса 0/ServiceModel/EntityDataService.svc/UsrGuestCollection(guid'3b42f755-1f62-4358-878c-47f460ab9e57')

json

{

"UsrRegistrationStatusId":"guid'a9d44061-de29-4578-9df6-d2f226573a06'"

}

полный ответ 

{
  "error": {
    "code": "4",
    "message": {
      "lang": "",
      "value": "An error occurred while processing this request."
    },
    "innererror": {
      "message": "An error occurred while processing this request.",
      "type": "System.Data.Services.DataServiceException",
      "stacktrace": "   at System.Data.Services.Serializers.ODataMessageReaderDeserializer.Deserialize(SegmentInfo segmentInfo)\r\n   at System.Data.Services.Serializers.Deserializer.HandlePutRequest()\r\n   at System.Data.Services.DataService`1.HandlePutOperation(RequestDescription description, IDataService dataService)\r\n   at System.Data.Services.DataService`1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)\r\n   at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)\r\n   at System.Data.Services.DataService`1.HandleRequest()",
      "internalexception": {
        "message": "Cannot convert a primitive value to the expected type 'Edm.Guid'. See the inner exception for more details.",
        "type": "Microsoft.Data.OData.ODataException",
        "stacktrace": "   at Microsoft.Data.OData.Json.ODataJsonReaderUtils.ConvertValue(Object value, IEdmPrimitiveTypeReference primitiveTypeReference, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, Boolean validateNullValue)\r\n   at Microsoft.Data.OData.Json.ODataJsonPropertyAndValueDeserializer.ReadPrimitiveValueImplementation(IEdmPrimitiveTypeReference expectedValueTypeReference, Boolean validateNullValue)\r\n   at Microsoft.Data.OData.Json.ODataJsonPropertyAndValueDeserializer.ReadNonEntityValueImplementation(IEdmTypeReference expectedTypeReference, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, CollectionWithoutExpectedTypeValidator collectionValidator, Boolean validateNullValue)\r\n   at Microsoft.Data.OData.Json.ODataJsonEntryAndFeedDeserializer.ReadEntryProperty(IODataJsonReaderEntryState entryState, IEdmProperty edmProperty)\r\n   at Microsoft.Data.OData.Json.ODataJsonEntryAndFeedDeserializer.ReadEntryContent(IODataJsonReaderEntryState entryState, IEdmNavigationProperty& navigationProperty)\r\n   at Microsoft.Data.OData.Json.ODataJsonReader.ReadAtEntryStartImplementation()\r\n   at Microsoft.Data.OData.ODataReaderCore.ReadImplementation()\r\n   at Microsoft.Data.OData.ODataReaderCore.InterceptException[T](Func`1 action)\r\n   at System.Data.Services.Serializers.EntityDeserializer.ReadEntry(ODataReader odataReader, SegmentInfo topLevelSegmentInfo)\r\n   at System.Data.Services.Serializers.EntityDeserializer.Read(SegmentInfo segmentInfo)\r\n   at System.Data.Services.Serializers.ODataMessageReaderDeserializer.Deserialize(SegmentInfo segmentInfo)",
        "internalexception": {
          "message": "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).",
          "type": "System.FormatException",
          "stacktrace": "   at System.Guid.GuidResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument, String failureArgumentName, Exception innerException)\r\n   at System.Guid.TryParseGuidWithDashes(String guidString, GuidResult& result)\r\n   at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)\r\n   at System.Guid..ctor(String g)\r\n   at Microsoft.Data.OData.Json.ODataJsonReaderUtils.ConvertStringValue(String stringValue, Type targetType)\r\n   at Microsoft.Data.OData.Json.ODataJsonReaderUtils.ConvertValue(Object value, IEdmPrimitiveTypeReference primitiveTypeReference, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, Boolean validateNullValue)"
        }
      }
    }
  }
}

Так же обратите внимание, на формирование строка запроса, в примере изменения имени контакта с идентификатором 00000000-0000-0000-0000-000000000000 из коллекции контактов ContactCollection.

// Строка запроса:
// PUT <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection(guid'00000000-0000-0000-0000-000000000000')
// или
// MERGE <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection(guid'00000000-0000-0000-0000-000000000000')

Григорий Чех,

Сейчас выполняется запрос вида 

 PUT <Адрес приложения BPMonline>0/ServiceModel/EntityDataService.svc/UsrGuestCollection(guid'3b42f755-1f62-4358-878c-47f460ab9e57')

А если без двойных кавычек

Json

{

"UsrRegistrationStatusId":guid'a9d44061-de29-4578-9df6-d2f226573a06'

}

Григорий Чех,

Без двойных кавычек сработает ошибка парсинга json 

{

"UsrRegistrationStatusId":guid'a9d44061-de29-4578-9df6-d2f226573a06'

}

 "message": "Invalid JSON. A token was not recognized in the JSON content."

 

В принципе должно быть

{

"UsrRegistrationStatusId":"a9d44061-de29-4578-9df6-d2f226573a06"

}

А если попробовать поменять простое текстовое поле например Name (если оно есть в вашем объекте) запрос корректно отработает?

Григорий Чех,

Да если менять обычное текстовое поле всё проходит успешно.

Были проблемы с типами данных - числами и датой, та же ошибка с преобразованием типов, на дату решилось преобразованием строки к виду "2019-04-18T11:14:26.697Z" , с числом не получается воспроизвести.

{

"UsrRegistrationStatusId":"a9d44061-de29-4578-9df6-d2f226573a06"

}

На такой формат выводит ошибку приведенную во  2 коментарии 

Привидите полный код формирования запроса с установкой всех служебных заголовков и обратите внимание на примеры для c# 

Прошу прощёния, данном формате запрос работает корректно.

{

"UsrRegistrationStatusId":"a9d44061-de29-4578-9df6-d2f226573a06"

}

Извините что ввёл в заблуждение.

Проявилось не сразу.. запросы выполнял в rest api клиенте после перезапуска клиента данный формат успешно обновил запись.



Премного вам благодарен! Огромное спасибо за ваше время!

Есть и более сложный способ, там не просто голый Guid надо, а с упоминанием названия коллекции, как тут с полом:

{
    Name: 'John',
    BirthDate: new Date(123321123321),
    Gender: {__metadata: { uri: 'GenderCollection(guid\'FC2483F8-65B6-DF11-831A-001D60E938C6\')' }}
}

И в таком случае справочное поле пишется без Id в конце.

Больше примеров в этом обсуждении.

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

Я не могу найти где можно увидеть список файлов к Обращению.

Само обращение отображается по запросу 

***bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseCollection(guid'ae67f3b8-c319-4a59-9d97-f8585f6b3d33')

Но внутри него я не могу найти список прикрепленный файлов.

Вопрос.

Где искать ? 

Нравится

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

Для каждой детали используется свой адрес в OData. Файлы обращения, соответственно, будут: ***bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseFileCollection/. Там можно посмотреть Id файлов и связи с обращениями. А непосредственно скачивание производить в FileService.

Я правильно понял чтоб мне найти файл который принадлежит к обращению мне нужно считать все файлы которые отдает CaseFileCollection и пройти все skiptoken ? После того как считал найти в них ид моего обращения ? И лишь потом узнать что за файл.  

Нет ли другого метода ? Т.е. сделать какой-то запрос чтоб по ид обращения он выдал мне список файлов которые есть в данном обращении ? 

Конечно, все качать не надо. Можно наложить фильтр по полю связи с обращением. См. примеры тут.

не хватило разума мне понять.

view-source:https://*****.bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseFileCollection?$filter=Name eq 'WhatsApp Image 2018-01-16 at 14.15.07 (1).jpeg'

По такому запросу ответ отдает верный.



view-source:https://*****.bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseFileCollection?$filter=CaseId eq guid'829a0b1a-650b-4844-b664-59053f9434ad'

По этому запросу отдает Элемент коллекции с именем CaseId не найден



Что он от меня хочет ? 

CaseFileCollection?$filter=Case/Id eq guid'829a0b1a-650b-4844-b664-59053f9434ad'

 

Спасибо!

Никогда б не догадался. Ниже привожу рабочий пример.

https://*.bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseFileCollection?$filter=Case/Id eq guid'1f779f3d-60b4-4a2c-a4b4-43e2cf89d8f0'

ссылку выше про  FileService. Я почитал. Но результата опять нет. 

 

http://адрес_сайта/0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/935b6ecb-3509-4c8a-bc7e-03ab0661da24

Тут первый GUID — ID схемы ContactFile (видно в URL, если её открыть в дизайнере), второй — ID записи в таблице.



Я думал что по этому запросу https://*.bpmonline.com/0/ServiceModel/EntityDataService.svc/CaseFileCollection?$filter=Case/Id eq guid'1f779f3d-60b4-4a2c-a4b4-43e2cf89d8f0'

я узнаю ид файла. Но нет. Ид тут другой. И ID схемы CaseFileCollection Тоже у меня нет.

Вопрос. 

Где я должен получить эти ИД ? 

По ссылке написано всё верно. Первый Id — для схемы CaseFile посмотрите в дизайнере. Второй — Id нужной записи в этой таблице, которую Вы получите по результату CaseFileCollection.

Да, все верно. Я не туда смотрел. Спасибо.

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

Добрый день Уважаемые!

Есть необходимость через веб приложение посредством протокола OData создавать (обновлять) объекты. Проблема в следующем:

После успешной аутентификации через (Supervisor) http://servername/ServiceModel/AuthService.svc/Login и получения необходимых куки отправляю на

http://servername/0/ServiceModel/EntityDataService.svc/AccountCollection

POST запросом  json объект. В приложении использую Apache-HttpClient/4.5.6.

Ответ сервера

<code>









403 - Запрещено: Доступ запрещен.









Ошибка сервера



 

 

403 - запрещено. Доступ запрещен.



 

Предоставленные учетные данные не дают права на просмотр этого каталога или страницы.



 




 

При этом, если отправлять PUT  запрос на обновление существующего объекта - все работает. GET запросы тоже работают корректно.

В чем может быть проблема?

Заранее благодарен.

 

Нравится

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

Данил, проверь что в запрос добавления данных добавляется параметр BPMCSRF из запроса авторизации

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

Wireshark подтвердил наличие всех необходимых куки. Настроил доступ к объекту для внешних сервисов и проверил доступ к операциям OData. Ничего не помогает.

Создал нового пользователя. Под новым пользователем смог получить  (get) данные только после внесения в группу SystemAdministartors. Post запросы - та же ошибка.

Такое может быть, если что-то неправильно в заголовках POST-запроса.

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

 Вручную устанавливаю только:

Content-Type = "application/json"

Accept = "application/json;odata=verbose"

Остальные устанавливаются автоматически при аутентификации. Пробовал двумя способами 1) Apache-HttpClient/4.5.6  и  2) RESTClient браузер Firefox - результат тот же.

Например, не передались обе куки, обычная авторизационная и BPMCSRF.

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

curl запросы

1) Аутентификация внешних запросов к bpm'online, запись куку в файл

curl -i -X POST -H "Content-Type: application/json" -d "{\"UserName\":\"Supervisor\", \"UserPassword\":\"Secret\"}" -c "D:\cookie.txt" "http://myserver.com/ServiceModel/AuthService.svc/Login"

Успешно.

2) Проверка аутентификации и правильности куки - запрос на изменение колонки Name объекста Account. Используем файл куки созданный предыдущим запросом

curl -i -X PUT -H "Content-Type: application/json;odata=verbose" -H "Accept: application/json;odata=verbose" -d "{\"Name\":\"Our company_test\"}" -b "D:\cookie.txt" -c "D:\cookie.txt" "http://myserver.com/0/ServiceModel/EntityDataService.svc/AccountCollection(guid'E308B781-3C5B-4ECB-89EF-5C1ED4DA488E')"

Успешно.

3) Запрос на создание объекта BankAccount

curl -i -X POST -H "Content-Type: application/json" -H "Accept: application/json;odata=verbose" -b "D:\cookie.txt" -c "D:\cookie.txt" -d "{\"Id\":\"8080EDFF-9858-5D90-E053-2413A8C0E8DE\", \"CreatedOn\":\"Jan 29, 2019 9:50:25 AM\", \"CreatedById\":\"410006E1-CA4E-4502-A9EC-E54D922D2C00\", \"BankAccountNumber\":\"123456\"}" "http://myserver.com/0/ServiceModel/EntityDataService.svc/BankAccountCollection"

Ответ - ошибка 403 из вопроса.

Куки из файла

BPMLOADER    acth1svm4chyo1kde1tyhabi

.ASPXAUTH    F87665E30ADF2706A530B217A9EEBD49F7970A16EE377079185607C2675CDEE780E8CEF53C210C88579B063BA610E934AA43B9BC9995684C9BE83B3DCF65DEF3F8396A000BAE95E4EAB56B10C83BAEC684CDCA449499B5B98109C4281A07D3AC55DC9CE553850D8C5F0145C2B5E93661FB1DB3CDFDD5390C7B52955F365F0C86FBAE51F5AE6800B74F59DEB8984F38EFB1FB60EE9571CE7BAC926E838E8D3BDA6EB756270AAF1DD747094A62A68EA6B0E300216C474299FBF7BDD2C5AC86CCBC020BE29D480523ECDEE2F7E15A3E46FA7AD588401C8D37CB25E409975C755B63F5FD49989A5EFBBA3DA95590F325876DB911845D2A81DBE30B98A36CC4BEC373DC1C746C7D8EE7AE62658F60FD013C66A5F67023E0FCE30F15296A1686F9A74D01133441519B3EA7A5A3FBD62BBFC757665AE769CF0260E5E20EB963DD3BD3D9EBB47206A9B9B1B44E8D53048EA12B402290512509EC00733232B9DFEBB7DD2D2643E78A

BPMCSRF    u2jumlmWDoKSYOpQwfgJjO

UserName    83|117|112|101|114|118|105|115|111|114

BPMSESSIONID    4zcngupbd5iwesppbeux5mrr

Это два разных объекта, Account и BankAccount. Возможно, Вы разрешили всё по одному, а пытаетесь добавлять в другой.

Нет, пример с BankAccount привел из-за соображений компактности. Все доступы к объектам для внешних сервисов настроены. Пробовал Account, Contract, BankAccount  и Activity из примера академии(https://academy.terrasoft.ru/documents/technic-sdk/7-13/vypolnenie-zapr…) Результат тот же.

BPMCSRF нужно передавать не только в куках, а и отдельным заголовком. См. статью по отправке запросов из фиддлера.

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

 Спасибо БОЛЬШОЕ! После добавления BPMCSF в хэдэр - все получилось.

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

Шаги воспроизведения:

Сайт клиента:

Версия: 7.12 Service Ent

 

Коллеги, требуется помощь.

По штатному функционалу https://academy.terrasoft.ru/documents/technic-sdk/7-13/rabota-s-obekta….

При добавлении пользователя в коллекцию SysAdminUnitCollection при сохранении вылетает ошибка, хотя при создании, например Контактов - всё ОК:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>4ForbiddenForbiddenSystem.Data.Services.DataServiceException   at System.Data.Services.DataServiceConfiguration.CheckResourceRights(ResourceSetWrapper container, EntitySetRights requiredRights)&#xD;

   at System.Data.Services.Serializers.Deserializer.HandlePostRequest()&#xD;

   at System.Data.Services.DataService`1.HandlePostOperation(RequestDescription description, IDataService dataService)&#xD;

   at System.Data.Services.DataService`1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)&#xD;

   at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)&#xD;

   at System.Data.Services.DataService`1.HandleRequest()

Авторизуюсь в сервисе под Supervisor.

Доступ к операциям и Доступ к объекту для внешних сервисов добавлен для SysAdminUnit на чтение, добавление, удаление, изменение.

Заранее благодарен за помощь.

Нравится

2 комментария

В коде веб-сервиса жёстко зашиты права только для чтения, если схема начинается на «Sys» или «VwSys» (с небольшим списком исключений).

Значит, добавление по OData для этой таблицы применять нельзя.

Спасибо за информацию!

Ну и дела!

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

Всем доброго времени суток.

Было бы замечательным реализовать определение откуда "пришло" действие из СРМ или же осуществили добавление/изменение/удаление через API.

Например некий маркер IsFromAPI = true/false

Это касается интеграции по протоколу OData.

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

А зачем плодить сущности?

Можно добавить в объект обычное логическое поле IsFromAPI и при записи в объект по OData писать туда true.

Можно завести отдельного пользователя только для интеграций и работать по OData под ним. Тогда всё будет видно в полях «создал» и «изменил».

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

Подскажите пожалуйста, в каком формате содержится фильтр в поле 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».

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

Добрый день.

Есть ли возможность массово поменять значения, например, объединив использование $filter и MERGE? Или единственный вариант по идентификатору?

Цели 2:

1. Действительно массово заменить общее значение на другое

2. Использовать кастомный идентификатор, известный внешней системе, без необходимости каждый раз разрешать его в guid.

Подход "в лоб" вернул ошибку

Query options $select, $expand, $filter, $orderby, $inlinecount, $skip, $skiptoken and $top are not supported by this request method or cannot be applied to the requested resource.

Может, просто синтаксис чуть неверен?

Отправленный запрос (по сути тоже по Id)

curl -X MERGE -H 'Content-Type: application/json;odata=verbose' -H 'Accept: application/atom+xml' -i 'http://terapp-t.hq.eximb.com/0/ServiceModel/EntityDataService.svc/Accou? eq '\''648dbb58-2aea-578d-e053-2413a8c01794'\' --data '{Name: '\''Other name'\''}'

Нравится

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

Вы уверенны что правильно передали название объекта те что в системе есть объект Accou очень похоже что вы имели ввиду Account (Контрагент) но недокопипастили!

Если хотите получать помощь по ошибке приводите полностью описание ошибки.

В фильтре можно строить условия поиска по любым полям, но быстро и надежно работать именно с Id!

 

Григорий Чех,

 

Спасибо за ответ, но я пока не уверен, что хорошо объяснил свою задачу. Мне бы хотелось получить аналог update Account set Name='New name' where Name='Old Name'; я представляю, как сделать аналог select, но модифицировать могу только по первичному ключу

update Account set Name='New name' where Id='{61402C80-BB18-45FC-89A2-5BBFAC1A53F2}' через AccountCollection(guid'61402c80-bb18-45fc-89a2-5bbfac1a53f2')

 

Мой запрос выглядит так:

curl -X PUT -H 'Accept: application/atom+xml' -H 'Content-Type: application/json;odata=verbose' -i 'http://terapp-d.hq.eximb.com/0/ServiceModel/EntityDataService.svc/Accou… eq guid'\''61402c80-bb18-45fc-89a2-5bbfac1a53f2'\' --data '{Name: "Other name3"}'

Ответ:

 

    Status Code: 405 Method Not Allowed

    Cache-Control: private

    Content-Length: 1197

    Content-Type: application/xml;charset=utf-8

    DataServiceVersion: 1.0;

    Date: Fri, 21 Sep 2018 10:03:14 GMT

    Server: Microsoft-IIS/8.5

    X-AspNet-Version: 4.0.30319

    X-Content-Type-Options: nosniff

    X-Frame-Options: SAMEORIGIN

    X-Powered-By: ASP.NET

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?><error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><code>4</code><message xml:lang="">The URI 'http://terapp-d.hq.eximb.com/0/ServiceModel/EntityDataService.svc/Accou… eq guid'61402c80-bb18-45fc-89a2-5bbfac1a53f2'' is not valid for PUT operation. The URI must point to a single resource for PUT operations.</message><innererror><message>The URI 'http://terapp-d.hq.eximb.com/0/ServiceModel/EntityDataService.svc/Accou… eq guid'61402c80-bb18-45fc-89a2-5bbfac1a53f2'' is not valid for PUT operation. The URI must point to a single resource for PUT operations.</message><type>System.Data.Services.DataServiceException</type><stacktrace>   в System.Data.Services.DataService`1.HandlePutOperation(RequestDescription description, IDataService dataService)&#xD;

   в System.Data.Services.DataService`1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)&#xD;

   в System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)&#xD;

   в System.Data.Services.DataService`1.HandleRequest()</stacktrace></innererror></error>

По поводу Accou - это валидатор сайта укоротил url, он был перенесен через клипборд прямо из браузера

The URI must point to a single resource for PUT operations!!!

Делайте в два прохода вызовите фильтр и получите коллекцию id пробежитесь по ним и проапдєйтите записи. Или используйте другие механизмы. (БП или кодом вариантов много)

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

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

Это не вариант, ищется generic решение, как заткнуть каждую конкретную дыру, мы и так знаем, но их ожидается неопределенное количество :)

 

Это вариант. Если считаете, что это «дыра» и такое требуется массово, делайте свой универсальный конфигурационный веб-сервис, заточенный под потребности.

Например, в bpm'online loyalty были специальные веб-сервисы и их методы для чтения, добавления, изменения контактов, карт, покупок и прочих сущностей. В любом случае специализированная логика будет работать быстрее стандартной, которая будет гонять тысячу Id туда и обратно, а потом тысячу раз обновлять по одной записи.

Итого ответ на 21.09.2018 такой:

указанная функциональность включена в OData V4.01, поэтому ожидать ее в bpm'online в ближайшее время бессмысленно; нужно искать обходные решения.

Начать искать можно с комментариев выше этого ^.

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

 спасибо, но как я уже написал, это не подходящий нам вариант по причине ограниченности типов входных параметров и, как следствие, необходимости либо выполнения серьезных трансформаций на уровне сервреа bpm'online, либо разработки многочисленных частных решений.

В текстовом параметре можно сериализировать какие угодно значения тем же JSON. Или передавать команды с любой разметкой, хоть прямо слать SQL-запросы (но это очень небезопасно, лучше так не делать).

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

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