Работа с BPMonline через OData с помощью WCF клиента

Начиная с версии 5.3, в BPMonline появилась возможность интеграции с другими приложениями через протокол OData (www.odata.org). Рассмотрим пример интеграции с использованием данного протокола, реализованный на Microsoft Visual Studio. В приведенных примерах некоторые проверки и обработка исключений были специально пропущены для улучшения наглядности кода.
Схема взаимодействия стороннего приложения с BPMonline через протокол OData изображена на рисунке:

screenshot

Создание WCF клиента

WCF клиент может быть создан путем генерации прокси с помощью Microsoft Visual Studio.
Щелкните правой клавишей мыши по проекту, в котором должна быть реализована интеграция, и выберите комадну «Add Service Reference…». В открывшемся диалоговом окне введите адрес веб-сервиса BPMonline и пространство имен, после чего нажмите на кнопку «Go». Вам будет предложено ввести имя пользователя BPMonline и пароль. Это нужно для того, чтобы подключиться к указанному сервису BPMonline. Полученные от сервиса метаданные будут использованы для генерации прокси-классов, необходимых для дальнейшей работы.

screenshot

После нажатия на кнопку «ОК» будут созданы прокси-классы. Вы сможете обращаться к ним, используя пространство имен BPMonlineServiceReference. Данное пространство имен необходимо включить в блок using. Сгенерированные классы находятся в файле Reference.cs, который Вы можете отобразить, выполнив команду «Show All Files» в меню «Project».

Подготовка

Добавьте необходимые директивы:

using System.Data.Services.Client;
using ODataTestClient.BPMonlineServiceReference;

Для работы с приложением через протокол OData необходимо обращаться к веб-сервису, который обеспечивает эту возможность. Веб-сервис доступен по адресу:

имя сервера> + "/WebApp/0/ServiceModel/EntityDataService.svc/"

Рекомендуется объявить в коде соответствующую константу, например:

private static readonly Uri dataSeviceUri = new Uri("http://localhost:2376/WebApp/0/ServiceModel/EntityDataService.svc/");

Авторизация

Запросы к BPMonline должны быть авторизованы. BPMonline поддерживает basic аутентификацию. Самый простой способ авторизации при этом – передача учетных данных в соответствующее свойство экземпляра класса BPMonline.
Например:

var context = new BPMonline(dataSeviceUri);
context.Credentials = new NetworkCredential("UserName", "UserPassword");

Получение списка записей

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

var context = new BPMonline(dataSeviceUri);
context.Credentials = new NetworkCredential("UserName", "UserPassword");
var responce = (context.ContactCollection).Execute() as QueryOperationResponseContact>;
while (responce != null) {
        foreach (var entry in responce) {
                // выполнение операций с контактом
        }
        var continuationToken = responce.GetContinuation();
        responce = continuationToken != null ? context.Execute(continuationToken) : null;
}

В противном случае можно опустить получение ссылки на следующую порцию данных.

Создание записи

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

var contactId = Guid.NewGuid();
Contact contact = new Contact() {
        Id = contactId,
        Name = "John Smith",
};
Account account = new Account() {
        Id = Guid.NewGuid(),
        Name = "Company"
};
contact.Account = account;
var context = new BPMonline(dataSeviceUri);
context.AddToAccountCollection(account);
context.AddToContactCollection(contact);
context.SetLink(contact, "Account", account);
context.Credentials = new NetworkCredential("UserName", "UserPassword");
DataServiceResponse responces = context.SaveChanges(SaveChangesOptions.Batch);

Изменение записи

var context = new BPMonline(dataSeviceUri);
context.Credentials = new NetworkCredential("UserName", "UserPassword");
var updContact = context.ContactCollection.Where(c => c.Id == contact.Id).First();
updContact.Name = "Johny";
context.UpdateObject(updContact);
responces = context.SaveChanges(SaveChangesOptions.Batch);

Удаление записи

context = new BPMonline(dataSeviceUri);
context.Credentials = new NetworkCredential("UserName", "UserPassword");
var deleteContact = context.ContactCollection.Where(c => c.Id == contact.Id).First();
context.DeleteObject(deleteContact);
responces = context.SaveChanges(SaveChangesOptions.Batch);

Нравится

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

В случае если не удалось создать WCF клиент описанным в статье способом.
Заходим в браузере на ссылку:

<имя сервера> + "/0/ServiceModel/EntityDataService.svc/$metadata"

Видим примерно такую картину:

Сохраняем полученный xml документ на диске. Я у себя сохранил как C:\metadata.xml.
Далее следуем по пунктам указанным в статье. Когда доходим до открытого окна "Add Service Reference". Вместо ссылки на сервис в поле адреса вставляем путь к нашему файлу с добавлением префикса file://:

После чего нажмите на кнопку «Go» и следуйте дальнейшим инструкциям из статьи

Подскажите, что нужно вызвать чтоб получить права (уровень доступа) на каждую элемент коллекции, а ещё лучше до поля в каждом классе.

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

Пример:

<collection href="ResourceFileInfoCollection">
<atom:title>ResourceFileInfoCollection</atom:title>
</collection>
<collection href="AccountCollection">
<atom:title>AccountCollection</atom:title>
</collection>
<collection href="EmployeeCollection">
<atom:title>EmployeeCollection</atom:title>
</collection>
<collection href="ContactCollection">
<atom:title>ContactCollection</atom:title>
</collection>
<collection href="ContactSalutationTypeCollection">
<atom:title>ContactSalutationTypeCollection</atom:title>
</collection>
<collection href="GenderCollection">
<atom:title>GenderCollection</atom:title>
</collection>
<collection href="ContactDecisionRoleCollection">
<atom:title>ContactDecisionRoleCollection</atom:title>
</collection>

У сервиса OData нет отдельного администрирования.
Все объекты, поля объектов и записи полностью администрируются стандартными средствами BPMonline.

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

За более детальной информацией по настройке прав в BPMonline, пожалуйста, обратитесь в тех. поддержку.

Игорь, а как на счёт такой вещи как - поле доступно для просмотра но нет возможности к редактированию? Чем веб-сервис может мне помочь в этом?

Это тоже решается правами на колонку или запись в целом.
Есть три уровня прав на каждую операцию (чтение, редактирование и удаление).
Каждую из операций можно запретить, разрешить и разрешить с правом делегирования.

Если при переходе по ссылке ".../0/ServiceModel"
появляется сообщение HTTP Error 403.14 - Forbidden

Убедитесь что у вас в системе BPMonline есть настройка Прав доступа к операциям
CanUseODataService / Доступ к OData

День добрый.
А как провести каскадное чтение данных.
Например, согласно коду получаю список заказов

bpm = new BPMonline(new Uri(_server));
bpm.Credentials = new NetworkCredential(_user, _password);
var responce = (bpm.OrderCollection).Execute() as QueryOperationResponse;
while (responce != null)
{
foreach (var order in responce)
{
list.Add(order);
}
var continuationToken = responce.GetContinuation();
responce = continuationToken != null ? bpm.Execute(continuationToken) : null;
}

Но все дочерние элементы равны null

order.Account = null
order.Owner = null
order.Contact = null
order.Status = null
Хотя они заполнены.

Может для каждого дочернего элемента надо отдельно догружать данные?

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