Обновить запись раздела

Сложный

Пример. Создать консольное приложение, которое, используя класс UpdateQuery, обновит контакт "Иванов Иван Иванович" раздела Контакты (Contacts). Для этой записи добавьте в колонку Email значение "i.ivanov@creatio.com".

1. Создать и настроить проект консольного приложения C# 

Предварительно выполните пример чтения записей в стороннем приложении, описанный в статье Добавить кнопку для чтения записей раздела [Контакты].

Чтобы создать и настроить проект консольного приложения C#:

  1. Используя среду разработки Microsoft Visual Studio (версии не ниже 2017), создайте проект консольного приложения Visual C#.

    Работа в Microsoft Visual Studio подробно описана в статье Разработать C# код в пользовательском проекте.

  2. Укажите в качестве названия проекта, например, DataServiceUpdateExample.
  3. Свойству проекта Target framework установите значение ".NET Framework 4.7".
  4. В секцию References проекта добавьте зависимости от библиотек:
    • System.Web.Extensions.dll — библиотека классов, входящая в .NET Framework.
    • Terrasoft.Core.dll — библиотека основных классов серверного ядра приложения. Находится по пути ...\Terrasoft.WebApp\bin\Terrasoft.Core.dll.
    • Terrasoft.Nui.ServiceModel.dll — библиотека классов служб приложения. Находится по пути ...\Terrasoft.WebApp\bin\Terrasoft.Nui.ServiceModel.dll.
    • Terrasoft.Common.dll — библиотека основных классов серверного ядра приложения. Находится по пути ...\Terrasoft.WebApp\bin\Terrasoft.Common.dll.
  5. В файл исходного кода приложения добавьте директивы using.
    Добавление директив using
    using System;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Collections.Generic;
    using Terrasoft.Nui.ServiceModel.DataContract;
    using Terrasoft.Core.Entities;
    using System.Web.Script.Serialization;
    using Terrasoft.Common;
    

2. Добавить объявление полей и констант 

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

Добавление объявления полей и констант
/* Основной URL приложения Creatio. Необходимо заменить на пользовательский. */
private const string baseUri = @"http://example.creatio.com";
/* Строка запроса к методу Login сервиса AuthService.svc. */
private const string authServiceUri = baseUri + @"/ServiceModel/AuthService.svc/Login";
/* Строка пути запроса UpdateQuery. */
private const string updateQueryUri = baseUri + @"/0/DataService/json/reply/UpdateQuery";
/* Cookie аутентификации Creatio. */
private static CookieContainer AuthCookie = new CookieContainer();

Здесь объявлены три строковых константных поля, с помощью которых формируются пути выполнения запросов на аутентификацию и запросов на чтение данных. Данные об аутентификации будут сохранены в поле AuthCookie.

3. Добавить метод, выполняющий аутентификацию 

Для доступа создаваемого приложения к сервису работы с данными DataService необходимо выполнить аутентификацию.

4. Реализовать запрос на добавление записи 

Поскольку объявленная ранее константа updateQueryUri содержит путь для отправки данных в формате JSON, то отправляемые данные необходимо предварительно сконфигурировать в виде строки, содержащей описание JSON-объекта, соответствующего контракту данных UpdateQuery. Это можно сделать непосредственно в строчной переменной, однако намного удобнее и безопаснее с точки зрения возможности возникновения ошибок создать экземпляр класса UpdateQuery, заполнить его свойства, а затем сериализовать его в строку.

Реализация запроса на добавление записи
/* Экземпляр класса запроса. */
 var updateQuery = new UpdateQuery()
 {
     /* Название корневой схемы. */
     RootSchemaName = "Contact",
     /* Новые значения колонок. */
     ColumnValues = new ColumnValues()
     {
         /* Коллекция ключ-значение. */
         Items = new Dictionary<string, ColumnExpression>()
         {
             /* Колонка Email. */
             {
                 /* Ключ. */
                 "Email",
                 /* Значение — экземпляр класса выражения запроса к схеме объекта.
                 Конфигурирование колонки [Email]. */
                 new ColumnExpression()
                 {
                     /* Тип выражения запроса к схеме объекта — параметр. */
                     ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                     /* Параметр выражения запроса. */
                     Parameter = new Parameter()
                     {
                         /* Значение параметра. */
                         Value = "i.ivanov@creatio.com",
                         /* Тип данных параметра — строка. */
                         DataValueType = DataValueType.Text
                     }
                 }
             }
         }
     },
     /* Фильтры запроса. */
     Filters = new Filters()
     {
         /* Тип фильтра — группа. */
         FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.FilterGroup,
         /* Коллекция фильтров. */
         Items = new Dictionary<string, Filter>()
         {
              /* Фильтрация по имени. */
             {
                 /* Ключ. */
                 "FilterByName",
                 /* Значение. */
                 new Filter
                 {
                     /* Тип фильтра — фильтр сравнения. */
                     FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.CompareFilter,
                     /* Тип сравнения — начинается выражением. */
                     ComparisonType = FilterComparisonType.Equal,
                     /* Выражение, подлежащее проверке. */
                     LeftExpression = new BaseExpression()
                     {
                         /* Тип выражения — колонка схемы. */
                         ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn,
                         /* Путь к колонке. */
                         ColumnPath = "Name"
                     },
                     /* Выражение фильтрации. */
                     RightExpression = new BaseExpression()
                     {
                         /* Тип выражения — параметр. */
                         ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                         /* Параметр выражения. */
                         Parameter = new Parameter()
                         {
                             /* Тип данных параметра — текст. */
                             DataValueType = DataValueType.Text,
                             /* Значение параметра. */
                             Value = "Иванов Иван Иванович"
                         }
                     }
                 }
             }
         }
     }
 };
 /* Сериализация экземпляра класса запроса на добавление в JSON-строку. */
 var json = new JavaScriptSerializer().Serialize(updateQuery);

Здесь создается экземпляр класса UpdateQuery, в свойстве ColumnValues которого устанавливается значение "i.ivanov@creatio.com" для колонки Email. Чтобы это значение было применено только для определенной записи или группы записей, необходимо свойству Filters присвоить значение ссылки на корректно инициализированный экземпляр класса Filters. В данном случае в коллекцию фильтров добавлен единственный фильтр, который отбирает только те записи, у которых значение колонки ФИО (Name) равно "Иванов Иван Иванович".

5. Выполнить POST-запрос к DataService 

  1. Создайте экземпляр класса HttpWebRequest.
  2. Заполните свойства экземпляра.
  3. Присоедините к запросу созданную ранее строку с JSON-объектом.
  4. Выполните и обработайте результат запроса к сервису работы с данными DataService.
    Реализация POST-запроса
    /* Преобразование строки JSON-объекта в массив байтов. */
    byte[] jsonArray = Encoding.UTF8.GetBytes(json);
    /* Создание экземпляра HTTP-запроса. */
    var updateRequest = HttpWebRequest.Create(updateQueryUri) as HttpWebRequest;
    /* Определение метода запроса. */
    updateRequest.Method = "POST";
    /* Определение типа содержимого запроса. */
    updateRequest.ContentType = "application/json";
    /* Добавление полученных ранее аутентификационных cookie в запрос на получение данных. */
    updateRequest.CookieContainer = AuthCookie;
    /* Установить длину содержимого запроса. */
    updateRequest.ContentLength = jsonArray.Length;
    
    /* Добавление CSRF токена в заголовок запроса. */
    CookieCollection cookieCollection = AuthCookie.GetCookies(new Uri(authServiceUri));
    string csrfToken = cookieCollection["BPMCSRF"].Value;
    updateRequest.Headers.Add("BPMCSRF", csrfToken);
    
    /* Помещение JSON-объекта в содержимое запроса. */
    using (var requestStream = updateRequest.GetRequestStream())
    {
        requestStream.Write(jsonArray, 0, jsonArray.Length);
    }
    /* Выполнение HTTP-запроса и получение ответа от сервера. */
    using (var response = (HttpWebResponse)updateRequest.GetResponse())
    {
        /* Вывод ответа в консоль. */
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            Console.WriteLine(reader.ReadToEnd());
        }
    }