- загальні положення
- Створення проксі-класів з використанням утиліти DataServiceModel Metadata Utility Tool (DataSvcutil.exe)
- Створення проксі-класів в проекті клієнтського додатка Visual Studio
- Отримання колекції об'єктів сервісу
- 1) Приклад отримання колекції контактів через LINQ-запит
- 2) Приклад отримання колекції контактів неявним запитом до OData сервісу через об'єкт контексту
- 3) Приклад отримання колекції контактів явним запитом до OData сервісу через об'єкт контексту
- Отримання об'єкта з заданими характеристиками
- Створення нового об'єкта
- Зміна існуючого об'єкта
- видалення об'єкта
Доступ до сутностей bpm'online по протоколу OData надає веб-сервіс EntityDataService.svc:
Адреса сервісу OData
http [s]: // <ім'я_сервера> / <імя_пріложенія_bpm'online> + "/0/ServiceModel/EntityDataService.svc/"
Приклад адреси сервісу OData
http://myserver.com/bpmonlineWebApp/0/ServiceModel/EntityDataService.svc
загальні положення
Ключовим моментом в організації роботи WCF-клієнта є отримання метаданих сервісу і створення клієнтських проксі-класів. Клієнтську програму буде використовувати ці класи-посередники для обміну даними з веб-сервісом.
Таким чином, щоб реалізувати клієнтську програму .NET, яке могло б працювати з OData -Сервис bpm'online, необхідно:
- Створити. NET проект, в якому буде реалізована інтеграція з bpm'online.
- Згенерувати клієнтські проксі-класи сервісу EntityDataService.svc.
- Створити екземпляр контексту середовища виконання сервісу EntityDataService.svc.
- Реалізувати клієнтську бізнес-логіку інтеграції з використанням методів створеного екземпляра проксі-класу.
Генерація проксі-класів на клієнті можлива декількома способами, розглянутими нижче.
Створення проксі-класів з використанням утиліти DataServiceModel Metadata Utility Tool (DataSvcutil.exe)
DataSvcUtil.exe є програмою командного рядка, що надається сервісами WCF Data Services, яка використовує канал OData і формує клієнтські класи служби даних, необхідні для доступу до служби даних з клієнтського застосування .NET Framework. Ця програма формує класи даних з використанням таких джерел метаданих:
Програма DataSvcUtil.exe встановлена в каталозі .NET Framework.
Зазвичай це папка C: \ Windows \ Microsoft.NET \ Framework \ v4.0. Для 64-розрядних версій систем це папка C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.
Формат виклику утиліти DataSvcutil.exe
datasvcutil / out: file [/ in: file | / Uri: serviceuri] [/ dataservicecollection] [/ language: devlang] [/ nologo] [/ version: ver] [/ help]
Більш детальна інформація по утиліті DataSvcutil.exe приведена в соответстувующем розділі MSDN .
Створення проксі-класів в проекті клієнтського додатка Visual Studio
Проксі-класи для клієнта WCF можуть бути створені безпосередньо з Visual Studio. Для цього необхідно виконати послідовність дій:
- Клацнути правою клавішею миші по проекту, в якому планується реалізація інтеграції з bpm'online, вибрати в контекстному меню пункт Add Service Reference ...
- У діалоговому вікні в полі Address ввести повну адресу OData -Сервис EntityDataService.svc.
- Натиснути на кнопку Go. В результаті відкриється вікно аутентифікації сервісу, в якому необхідно вказати ім'я та пароль користувача bpm'online. Якщо аутентифікація пройшла успішно, у вікні Services відобразяться підтримувані сервісом суті.
- В поле Namespase вказати ім'я простору імен, в якому будуть розташовані згенеровані проксі-класи. Наприклад, bpm'onlineServiceReference. Посилання на цей простір імен в подальшому необхідно додати в блок using коду проекту.
- Натиснути кнопку ОК, після чого будуть згенеровані проксі-класи. При цьому в проект буде додано новий файл коду Reference.cs, що містить опис проксі-класів, які тепер можуть використовуватися для звернення і взаємодії з ресурсами сервісу даних як з об'єктами.
ДО ВІДОМА
У Visual Studio є можливість генерувати проксі-класи сервісу з збереженого на диску файлу метаданих сервісу. Для цього необхідно виконати п.1 інструкції, потім в діалоговому вікні Address ввести повний шлях до файлу метаданих з префіксом "file: //".
Приклад: file: // C: /metadata.xml "
Далі виконати пп. 3 - 5 інструкції.
Після генерації проксі-класів сервісу в проект додається посилання на збірку Microsoft.Data.Services.Client.dll, яка реалізує підтримку протоколу OData v.3. Якщо з якої-небудь причини в клієнтському додатку необхідно використовувати протокол більш ранньої версії, то посилання на відповідну збірку необхідно додати вручну.
Дана клієнтська бібліотека дозволяє виконувати запити до сервісу даних EntityDataService.svc, використовуючи стандартні шаблони програмування .NET Framework, включаючи використання мови запитів LINQ.
Для успішної компіляції наведених нижче прикладів в код проекту необхідно додати:
директиви Using
using System; using System.Data.Services.Client; using System.Net; using Terrasoft.Sdk.Examples.BPMonlineServiceReference; using System.Linq;
Оголошення змінної адреси сервісу OData
private static Uri serverUri = new Uri ( "http: // <ім'я_сервера> / <імя_пріложенія> /0/ServiceModel/EntityDataService.svc/");
Отримання колекції об'єктів сервісу
Для отримання колекції об'єктів сервісу використовується універсальний клас DataServiceQuery , Який являє собою запит до сервісу, який повертає колекцію сутностей конкретного типу.
Щоб виконати запит до сервісу даних EntityDataService.svc, попередньо необхідно створити екземпляр об'єкта контексту середовища додатки bpm'online.
Необхідно пам'ятати, що всі зовнішні запити до веб-сервісів bpm'online повинні бути автентифіковано. Детальніше про способи аутентифікації можна ознайомитися в статті Аутентифікація зовнішніх запитів до веб-сервісів bpm'online .
Далі в прикладах буде використана forms-аутентифікація, реалізована на основі прикладі з вищевказаної статті.
Для реалізації forms-аутентифікації був створений клас LoginClass з полями authServiceUri (рядок запиту до методу Login аутентификационного сервісу AuthService.svc) і AuthCookie (Cookie аутентифікації bpm'online), а також методом TryLogin (string userName, string userPassword), який виконує аутентифікацію користувача і зберігає відповідь сервера в поле AuthCookie.
Додатково створюємо метод OnSendingRequestCookie (object sender, SendingRequestEventArgs e), який буде викликаний у відповідь на подію примірника контексту SendingRequest (створення нового екземпляра HttpWebRequest).
У методі OnSendingRequestCookie виконується аутентифікація користувача, а отримані у відповідь Cookies додаються в запит на отримання даних.
static void OnSendingRequestCookie (object sender, SendingRequestEventArgs e) {// Виклик методу класу LoginClass, що реалізує аутентифікацію переданого в параметрах методу користувача. LoginClass.TryLogin ( "BPMUserName", "BPMUserPassword"); var req = e.Request as HttpWebRequest; // Додавання отриманих аутентифікаційних cookie в запит на отримання даних. req.CookieContainer = LoginClass.AuthCookie; e.Request = req; }
Виконання запиту до сервісу можливо одним з наступних способів:
- Виконання запиту LINQ до іменованого об'єкта DataServiceQuery , Який отримано з контексту сервісу.
- Неявне перерахування об'єкта DataServiceQuery , Який отримано з контексту сервісу.
- Явний виклик методу Execute об'єкта DataServiceQuery або BeginExecute для асинхронного виконання.
Нижче наведені приклади доступу до об'єктів EntityDataService.svc кожним з наведених способів.
1) Приклад отримання колекції контактів через LINQ-запит
Даний приклад демонструє, як визначити і виконати запит LINQ, який повертає всі сутності контактів сервісу EntityDataService.svc.
public static void GetOdataCollectioByLinqWcfExample () {// Створення контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); try {// Побудова запиту LINQ для отримання колекції контактів. var allContacts = from contacts in context.ContactCollection select contacts; foreach (Contact contact in allContacts) {// Виконання дій з контактами. }} Catch (Exception ex) {// Обробка помилок. }}
2) Приклад отримання колекції контактів неявним запитом до OData сервісу через об'єкт контексту
В даному прикладі демонструється, як використовувати контекст для неявного виконання запиту, повертає всі сутності контактів сервісу EntityDataService.svc.
public static void GetOdataCollectionByImplicitRequestExample () {// Створення об'єкта контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); try {// Визначення неявного запиту до сервісу для отримання колекції контактів. DataServiceQuery <Contact> allContacts = context.ContactCollection; foreach (Contact contact in allContacts) {// Виконання дій з контактами. }} Catch (Exception ex) {// Обробка помилок. }}
3) Приклад отримання колекції контактів явним запитом до OData сервісу через об'єкт контексту
Даний приклад показує, як використовувати контекст DataServiceContext для явного виконання запиту до сервісу EntityDataService.svc, який повертає всі сутності контактів.
public static void GetOdataCollectionByExplicitRequestExample () {// Визначення Uri запиту до сервісу, який повертає колекцію контактів. Uri contactUri = new Uri (serverUri, "ContactCollection"); // Створення об'єкта контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); try {// Виконання явного запиту до сервісу викликом методу Execute <> (). foreach (Contact contact in context.Execute <Contact> (contactUri)) {// Виконання дій з контактами. }} Catch (Exception ex) {// Обробка помилок. }}
Отримання об'єкта з заданими характеристиками
public static void GetOdataObjectByWcfExample () {// Створення контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); // var contact = context.ContactCollection.Where (c => c.Name.Contains ( "User")). First (); // Виконання дій над контактом. }
Створення нового об'єкта
public static void CreateBpmEntityByOdataWcfExample () {// Створення нового контакту, ініціалізіція властивостей. var contact = new Contact () {Id = Guid.NewGuid (), Name = "New Test User"}; // Створення і ініціалізація властивостей нового контрагента, до якого відноситься створюваний контакт. var account = new Account () {Id = Guid.NewGuid (), Name = "Some Company"}; contact.Account = account; // Створення контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); // Додавання створеного контакту в колекцію контактів моделі даних сервісу. context.AddToAccountCollection (account); // Додавання створеного контрагента в колекцію контрагентів моделі даних сервісу. context.AddToContactCollection (contact); // Установка зв'язку між створеними контактом і контрагентом в моделі даних сервісу. context.SetLink (contact, "Account", account); // Збереження змін даних в BPMonline одним запитом. DataServiceResponse responces = context.SaveChanges (SaveChangesOptions.Batch); // Обробка відповідей від сервера. }
Зміна існуючого об'єкта
public static void UpdateBpmEntityByOdatetWcfExample () {// Створення контексту програми BPMonline. var context = new BPMonline (serverUri); // Визначення методу, який додає аутентифікаційні cookie при створенні нового запиту. context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); // З колллекціі контактів вибирається той, за яким буде змінюватися інформація. var updateContact = context.ContactCollection.Where (c => c.Name.Contains ( "Test")). First (); // Зміна властивостей обраного контакту. updateContact.Notes = "New updated description for this contact." ; updateContact.Phone = "123456789"; // Збереження змін в моделі даних сервісу. context.UpdateObject (updateContact); // Збереження змін даних в BPMonline одним запитом. var responces = context.SaveChanges (SaveChangesOptions.Batch); }
видалення об'єкта
public static void DeleteBpmEntityByOdataWcfExample () {// Створення контексту програми BPMonline. var context = new BPMonline (serverUri); context.SendingRequest + = new EventHandler <SendingRequestEventArgs> (OnSendingRequestCookie); // З колекції контактів вибирається той об'єкт, який буде видалений. var deleteContact = context.ContactCollection.Where (c => c.Name.Contains ( "Test")). First (); // Видалення вибраного об'єкту з моделі даних сервісу. context.DeleteObject (deleteContact); // Збереження змін даних в BPMonline одним запитом. var responces = context.SaveChanges (SaveChangesOptions.Batch); // обробку відповідей від сервера. }