Документация по разработке bpm’online
PDF
Документация по разработке

Работа с объектами bpm'online по протоколу OData с использованием Http-запросов

Glossary Item Box

В данной статье будут рассмотрены следующие вопросы: 

    Для успешной компиляции приведенных ниже примеров в программный код необходимо добавить:

    Директивы Using

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Xml;
    using System.Xml.Linq; 
    

    Объявление переменных и констант

    // Строка адреса BPMonline сервиса OData.
    private const string serverUri = "http://<имя_сервера>/<имя_приложения_BPMonline>/0/ServiceModel/EntityDataService.svc/";
    private const string authServiceUtri = "http://<имя_сервера>/<имя_приложения_BPMonline>/ServiceModel/AuthService.svc/Login";
    
    // Ссылки на пространства имен XML.
    private static readonly XNamespace ds = "http://schemas.microsoft.com/ado/2007/08/dataservices";
    private static readonly XNamespace dsmd = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
    private static readonly XNamespace atom = "http://www.w3.org/2005/Atom"; 
    

    Операции работы с объектами и коллекциями объектов

    Получение коллекции объектов

    Для получения коллекции объектов используется HTTP-метод GET.

    Записи возвращаются постранично, по 40 записей на страницу. Если предполагается, что запрос вернет больше 40 записей, необходимо обеспечить получение следующей страницы по достижении конца текущей.

    В примере ниже демонстрируется использование конструкции $select для получения отдельных полей объекта. В результате выполнения запроса в примере будет возвращена коллекция контактов с полями Id и Name.

    В приведенном примере также используется Forms-аутентификация. Имя и пароль пользователя bpm'online передаются в параметрах метода GetOdataCollectionByAuthByHttpExample(string userName, string userPassword).

    // Строка запроса
    // GET <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection?select=Id,Name 
    
    public static void GetOdataCollectionByAuthByHttpExample(string userName, string userPassword)
    {
        // Создание запроса на аутентификацию.
        var authRequest = HttpWebRequest.Create(authServiceUtri) as HttpWebRequest;
        authRequest.Method = "POST";
        authRequest.ContentType = "application/json";
        var bpmCookieContainer = new CookieContainer();
        // Включение использования cookie в запросе.
        authRequest.CookieContainer = bpmCookieContainer;
        // Получение потока, ассоциированного с запросом на аутентификацию.
        using (var requestStream = authRequest.GetRequestStream())
        {
            // Запись в поток запроса учетных данных пользователя BPMonline и дополнительных параметров запроса.
            using (var writer = new StreamWriter(requestStream))
            {
                writer.Write(@"{
                                    ""UserName"":""" + userName + @""",
                                    ""UserPassword"":""" + userPassword + @""",
                                    ""SolutionName"":""TSBpm"",
                                    ""TimeZoneOffset"":-120,
                                    ""Language"":""Ru-ru""
                                    }");
            }
        }
        // Получение ответа от сервера. Если аутентификация проходит успешно, в объекте bpmCookieContainer будут 
        // помещены cookie, которые могут быть использованы для последующих запросов.
        using (var response = (HttpWebResponse)authRequest.GetResponse())
        {
            // Создание запроса на получение данных от сервиса OData.
            var dataRequest = HttpWebRequest.Create(serverUri + "ContactCollection?select=Id, Name")
                                    as HttpWebRequest;
            // Для получения данных используется HTTP-метод GET.
            dataRequest.Method = "GET";
            // Добавление полученных ранее аутентификационных cookie в запрос на получение данных.
            dataRequest.CookieContainer = bpmCookieContainer;
            // Получение ответа от сервера.
            using (var dataResponse = (HttpWebResponse)dataRequest.GetResponse())
            {
                // Загрузка ответа сервера в xml-документ для дальнейшей обработки.
                XDocument xmlDoc = XDocument.Load(dataResponse.GetResponseStream());
                // Получение коллекции объектов контактов, соответствующих условию запроса.
                var contacts = from entry in xmlDoc.Descendants(atom + "entry")
                               select new
                                   {
                                       Id = new Guid(entry.Element(atom + "content")
                                                          .Element(dsmd + "properties")
                                                          .Element(ds + "Id").Value),
                                       Name = entry.Element(atom + "content")
                                                   .Element(dsmd + "properties")
                                                   .Element(ds + "Name").Value
                                   };
                foreach (var contact in contacts)
                {
                    // Выполнение действий с контактами.
                }
            }
        } 
    

    ВАЖНО

    НА ЗАМЕТКУ

    Если необходимо отправлять запрос и получать ответ в формате JSON, укажите в заголовке запроса:

    Content-Type = "application/json"

    Accept = "application/json;odata=verbose"

    Если необходимо, чтобы запрос возвращал более, чем 40 записей за один раз, это можно реализовать с использованием параметра $top, в котором указывается требуемое количество возвращаемых запросом записей. Так, в приведенном ниже примере формируется строка запроса к сервису для получения первых 60 объектов коллекции контактов.

    Пример использования параметра $top

    string requestUri = serverUri + "ContactCollection?$top=60";
    

    В bpm'online поддерживается использование параметра $skip, который позволяет запрашивать у сервиса ресурсы, пропустив заданное количество записей.

    В приведенном ниже примере продемонстрировано формирование строки запроса к сервису для получения коллекции контактов, начиная с 11 записи.

    Пример использования параметра $skip

    string requestUri = serverUri + "ContactCollection?$skip=10";
    

    Ресурсы сервиса можно получать в отсотрированном виде. Для этого в запросе нужно использовать параметр $orderby [asc|desc], в котором указать, по какому полю выполнять сортировку результатов. Кроме того, для данного параметра можно указать одно из направлений сортировки:

    • по возрастанию (asc)
    • по убыванию (desc)

    По умолчанию используется сортировка по возрастанию (asc).

    В примере ниже формируется строка запроса к сервису для получения коллекции контактов, отсортированной по возрастанию значения поля Name.

    Пример использования параметра $orderby для сортировки по возрастанию

    string requestUri = serverUri + "ContactCollection?$orderby=Name";
    

    Параметры $top, $skip, $orderby можно использовать в различных комбинациях для получения конкретного фрагмента коллекции.

    Пример использования параметров $orderby, $top, $skip в комбинации

    string requestUri = serverUri + "ContactCollection?$top=4&$skip=1&$orderby=City/Name";
    

    Получение объекта с заданными характеристиками

    Для получения объекта используется HTTP-метод GET.

    Получение конкретного объекта, который отвечает определенным условиям (например, контакт с заданным Id или контрагент с определенным названием и т.д.) можно реализовать несколькими способами (в приведенных ниже примерах используется Basic-аутентификация запросов).

    Задание Id искомого объекта в качестве параметра коллекции

    // Строка запроса:
    // GET <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection(guid'00000000-0000-0000-0000-000000000000')
    
    public static void GetOdataObjectByIdExample()
    {
        // Id искомого объекта.
        string contactId = "00000000-0000-0000-0000-000000000000";
    
        // Формирование строки запроса к сервису.
        string requestUri = serverUri + "ContactCollection(guid'" + contactId + "')";
    
        // Создание объекта запроса к сервису.
        var request = HttpWebRequest.Create(requestUri) as HttpWebRequest;
        request.Method = "GET";
        request.Credentials = new NetworkCredential("BPMUserName", "BPMUserPassword");
        using (var response = request.GetResponse())
        {
            // Получение ответа от сервиса в xml-формате.
            XDocument xmlDoc = XDocument.Load(response.GetResponseStream());
            // Получение коллекции объектов контактов, соответствующих условию запроса.
            var contacts = from entry in xmlDoc.Descendants(atom + "entry")
                           select new
                               {
                                   Id = new Guid(entry.Element(atom + "content")
                                                     .Element(dsmd + "properties")
                                                     .Element(ds + "Id").Value),
                                   Name = entry.Element(atom + "content")
                                               .Element(dsmd + "properties")
                                               .Element(ds + "Name").Value
                                   // Инициализация свойств объекта, необходимых для дальнейшего использования.
                               };
            foreach (var contact in contacts)
            {
                // Выполнение действий над контактом.
            }
        }
    } 
    

     

    Данный способ можно использовать только в том случае, если необходимо получить объект с заданным идентификатором.

    Если в качестве параметров искомого объекта выступает не идентификатор объекта или искомый объект определяется несколькими параметрами, то необходимо использовать конструктцию $filter для определения параметров.

    Использование конструкции $filter для формирования сложного условия выбора объекта

    Конструкция $filter позволяет строить логические выражения условий выбора искомого объекта.

    В выражениях $filter можно использовать ссылки на свойства и литералы, а также строки, числа и логические выражения (true, false). Выражения $filter поддерживают арифметические, логические операции, а также операции группировки, операции со строками, датой и временем. Полный перечень операций конструкции $filter приведен в спецификации OData

    Рассмотрим пример получения объекта с заданным Id, используя для задания условия конструкции $filter.

    // Строка запроса:
    // GET <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection?$filter=Id eq guid'00000000-0000-0000-0000-000000000000'
    
    public static void GetOdataObjectByFilterConditionExample()
    {
        // Id искомого объекта.
        string contactId = "00000000-0000-0000-0000-000000000000";
        // Формирование строки запроса к сервису.
        string requestUri = serverUri + "ContactCollection?$filter = Id eq guid'" + contactId + "'";
        // Создание объекта запроса к сервису.
        var request = HttpWebRequest.Create(requestUri) as HttpWebRequest;
        request.Method = "GET";
        request.Credentials = new NetworkCredential("BPMUserName", "BPMUserPassword");
        using (var response = request.GetResponse())
        {
            // Получение ответа от сервиса в xml-формате.
            XDocument xmlDoc = XDocument.Load(response.GetResponseStream());
            // Получение коллекции объектов контактов, соответствующих условию запроса.
            var contacts = from entry in xmlDoc.Descendants(atom + "entry")
                           select new
                           {
                               Id = new Guid(entry.Element(atom + "content")
                                                 .Element(dsmd + "properties")
                                                 .Element(ds + "Id").Value),
                               Name = entry.Element(atom + "content")
                                           .Element(dsmd + "properties")
                                           .Element(ds + "Name").Value
                               // Инициализация свойств объекта, необходимых для дальнейшего использования.
                           };
            foreach (var contact in contacts)
            {
               // Выполнение действий над контактом.
            }
        }
    } 
    

    С помощью конструкции $filter можно создавать сложные условия по нескольким полям объекта.

    Ниже приведен пример возвращения коллекции объектов контактов, которые были созданы пользователем SomeUserName после 1.11.2012

    // Строка запроса:
    // GET <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection?$filter=CreatedOn gt datetime'2012-11-01' and CreatedBy/Name eq 'SomeUserName'
    
    public static void GetOdataObjectByFilterDiffConditionExample()
    {
        // Имя пользователя, который создал объекты.
        string userName = "BPMUserName";
        // Дата создания объектов.
        string datetime = "2012-11-01";
        // Формирование строки запроса к сервису.
        string requestUri = serverUri + "ContactCollection?$filter=CreatedOn gt datetime'" + datetime +
                                        "'and CreatedBy/Name eq '" + userName + "'";
        // Создание объекта запроса к сервису.
        var request = HttpWebRequest.Create(requestUri) as HttpWebRequest;
        request.Method = "GET";
        request.Credentials = new NetworkCredential(userName, "BPMUserPassword");
        using (var response = request.GetResponse())
        {
            // Получение ответа от сервиса в xml-формате.
            XDocument xmlDoc = XDocument.Load(response.GetResponseStream());
            // Получение коллекции объектов контактов, соответствующих условию запроса.
            var contacts = from entry in xmlDoc.Descendants(atom + "entry")
                           select new
                           {
                               Id = new Guid(entry.Element(atom + "content")
                                                 .Element(dsmd + "properties")
                                                 .Element(ds + "Id").Value),
                               Name = entry.Element(atom + "content")
                                           .Element(dsmd + "properties")
                                           .Element(ds + "Name").Value
                               // Инициализация свойств объекта, необходимых для дальнейшего использования.
                           };
            foreach (var contact in contacts)
            {
                // Выполнение действий над контактом.
            }
        }
    } 
    

    Больше примеров построения запросов с помощью конструкции $filter вы можете найти в статье "Примеры запросов на выборку с фильтрацией".

    Создание нового объекта

    Для создания объекта используется HTTP-метод POST.

    При этом необходимо сформировать тело запроса в формате Atom/XML или JSON таким образом, чтобы он содержал все необходимые поля объекта. Все возможные поля создаваемого объекта описаны в метаданных сервиса.

    ВАЖНО

    НА ЗАМЕТКУ

    Если необходимо отправлять запрос и получать ответ в формате JSON, укажите в заголовке запроса:

    Content-Type = "application/json"

    Accept = "application/json;odata=verbose"

    Ниже приведен пример создания нового контакта. В примере применяется Basic-аутентификация запроса.

    // Строка запроса:
    // POST <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection/
    
    public static void CreateBpmEntityByOdataHttpExample()
    {
        // Создание сообщения xml, содержащего данные о создаваемом объекте.
        var content = new XElement(dsmd + "properties",
                      new XElement(ds + "Name", "Иван Иванов"),
                      new XElement(ds + "Dear", "Иван"));
        var entry = new XElement(atom + "entry",
                    new XElement(atom + "content",
                    new XAttribute("type", "application/xml"), content));
        Console.WriteLine(entry.ToString());
        // Создание запроса к сервису, который будет добавлять новый объект в коллекцию контактов.
        var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "ContactCollection/");
        request.Credentials = new NetworkCredential("BPMUserName", "BPMUserPassword");
        request.Method = "POST";
        request.Accept = "application/atom+xml";
        request.ContentType = "application/atom+xml;type=entry";
        // Запись xml-сообщения в поток запроса.
        using (var writer = XmlWriter.Create(request.GetRequestStream()))
        {
            entry.WriteTo(writer);
        }
        // Получение ответа от сервиса о результате выполнения операции.
        using (WebResponse response = request.GetResponse())
        {
            if (((HttpWebResponse)response).StatusCode == HttpStatusCode.Created)
            {
                // Обработка результата выполнения операции.
            }
        }
    } 
    

    Изменение существующего объекта

    Для изменения записи используется HTTP-метод PUT (или MERGE в более новых версиях OData).

    ВАЖНО

    НА ЗАМЕТКУ

    Если необходимо отправлять запрос и получать ответ в формате JSON, укажите в заголовке запроса:

    Content-Type = "application/json"

    Accept = "application/json;odata=verbose"

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

    Ниже приведен пример изменения имени контакта с идентификатором 00000000-0000-0000-0000-000000000000 из коллекции контактов ContactCollection. В примере используется Basic-аутентификация запросов.

    // Строка запроса:
    // 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')
    
    
    public static void UpdateExistingBpmEnyityByOdataHttpExample()
    {
        // Id записи объекта, который необходимо изменить.
        string contactId = "00000000-0000-0000-0000-000000000000";
        // Создание сообщения xml, содержащего данные об изменяемом объекте.
        var content = new XElement(dsmd + "properties",
                new XElement(ds + "Name", "Новое имя")
        );
        var entry = new XElement(atom + "entry",
                new XElement(atom + "content",
                        new XAttribute("type", "application/xml"),
                        content)
                );
        // Создание запроса к сервису, который будет изменять данные объекта.
        var request = (HttpWebRequest)HttpWebRequest.Create(serverUri
                + "ContactCollection(guid'" + contactId + "')");
        request.Credentials = new NetworkCredential("BPMUserName", "BPMUserPassword");
        // или request.Method = "MERGE";
        request.Method = "PUT";
        request.Accept = "application/atom+xml";
        request.ContentType = "application/atom+xml;type=entry";
        // Запись сообщения xml в поток запроса.
        using (var writer = XmlWriter.Create(request.GetRequestStream()))
        {
            entry.WriteTo(writer);
        }
        // Получение ответа от сервиса о результате выполнения операции.
        using (WebResponse response = request.GetResponse())
        {
            // Обработка результата выполнения операции.
        }
    } 
    

    Удаление объекта

    Для удаления записи используется HTTP-метод DELETE.

    ВАЖНО

    НА ЗАМЕТКУ

    Если необходимо отправлять запрос и получать ответ в формате JSON, укажите в заголовке запроса:

    Content-Type = "application/json"

    Accept = "application/json;odata=verbose"

    В строке запроса необходимо указать коллекцию, объект которой удаляется, а в качестве параметра коллекции указать идентификатор удаляемого объекта.

    Ниже приведен пример удаления контакта с идентификатором 00000000-0000-0000-0000-000000000000 из коллекции контактов ContactCollection. В примере используется Basic-аутентификация запросов.

    // Строка запроса:
    // DELETE <Адрес приложения BPMonline>/0/ServiceModel/EntityDataService.svc/ContactCollection(guid'00000000-0000-0000-0000-000000000000')
    
    public static void DeleteBpmEntityByOdataHttpExample()
    {
        // Id записи объекта, который необходимо удалить.
        string contactId = "00000000-0000-0000-0000-000000000000";
        // Создание запроса к сервису, который будет удалять данные.
        var request = (HttpWebRequest)HttpWebRequest.Create(serverUri
                + "ContactCollection(guid'" + contactId + "')");
        request.Credentials = new NetworkCredential("BPMUserName", "BPMUserPassword");
        request.Method = "DELETE";
        // Получение ответа от сервися о результате выполненя операции.
        using (WebResponse response = request.GetResponse())
        {
            // Обработка результата выполнения операции.
        }
    } 
    

    Функции работы со строками

    BPMonine поддерживает следующие функции работы со строками протокола OData, которые могут быть применены для построения выражений конструкции $filter.

    Функция Пример строки запроса Результат выполнения запроса
    bool substringof(string po, string p) <Адрес сервиса>/ContactCollection?$filter=substringof('Smith', Name) Коллекция контактов, в имени которых присутствует подстрока 'Smith'
    string toupper(string p0) <Адрес сервиса>/ContactCollection?$filter=toupper(Name) eq 'TEST USER' Коллекция контактов, имя которых в верхнем регистре равно 'TEST USER'
    bool endswith(string p0, string p1) <Адрес сервиса>/ContactCollection?$filter=endswith(Name, 'User') Коллекция контактов, имя которых оканчивается подстрокой 'User'.
    int length(string p0) <Адрес сервиса>/ContactCollection?$filter=length(Name) gt 10 Коллекция контактов, длина имени которых больше 10 символов.
    string trim(string p0) <Адрес сервиса>/ContactCollection?$filter=trim(Name) eq 'Test User' Коллекция контактов, имя которых после удаления начальных и конечных пробелов равно 'Test User'.

    Полный перечень функций работы со строками протокола OData приведен в официальной спецификации OData.

    Функции работы с датой и временем

    BPMonine поддерживает следующие функции работы с датами протокола OData, которые могут быть применены для построения выражений конструкции $filter.

    Функция Пример строки запроса Результат выполнения запроса
    int year(DateTime p0) <Адрес сервиса>/ContactCollection?$filter=year(BirthDate) ge 1950 and year(BirthDate) le 1990 Коллекция контактов, чей год рождения находится в интервале от 1950 до 1990 гг. включительно.
    int month(DateTime p0) <Адрес сервиса>/ContactCollection?$filter=month(BirthDate) eq 5 Коллекция контактов, родившихся в мае месяце.
    int day(DateTime p0) <Адрес сервиса>/ContactCollection?$filter=day(BirthDate) eq 15 Коллекция контактов, родившихся 15 числа.
    Полный перечень функций работы с датами протокола OData приведен в официальной спецификации OData.

    Смотрите также

    © Terrasoft 2002-2019.

    Был ли данный материал полезен?

    Как можно улучшить эту статью?