Добрый день! Возникла проблема с передачей в БП параметров при использовании POST.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestUploadFiles
{
    using System.IO;
    using System.Net;
    using System.Net.Http;

    class Program
    {

        public class BPMonlineProcessEngineExample
        {
            // Uri приложения BPMonline.
            private static string serverUri = "http://192.168.5.3/";

            // Uri сервиса аутентификации BPMonline.
            private static string authServiceUri = "ServiceModel/AuthService.svc/Login";

            // Uri сервиса запуска процессов BPMonline.
            private static string executeProcessMethodPath = "0/ServiceModel/ProcessEngineService.svc";

            // Cookie аутентификации BPMonline.
            public static CookieContainer AuthCookie { get; set; }

            // Признак, прошла ли аутентификация на сервере BPMonline.
            public static bool IsAuthentificated
            {
                get
                {
                    return (AuthCookie != null);
                }
            }

            // Метод для аутентификации запроса к веб-сервису BPMonline.
            // Параметры:
            // userName - имя пользователя BPMonline,
            // userPassword - пароль пользователя BPMonline,
            // solutionName - имя конфигурации BPMonline.
            public static bool TryLogin(string userName, string userPassword, string solutionName)
            {
                // Формирование строки с аутентификационными данными.
                string authString = @"{
            "
"Language"":""Ru-ru"",
            "
"UserName"":""" + userName + @""",
            ""UserPassword"":""" + userPassword + @""",
            ""TimeZoneOffset"":-120
        }";
                byte[] authData = UTF8Encoding.UTF8.GetBytes(authString);

                // Переменная, в которую будут помещены возвращенные сервером cookie в случае успешной аутентификации.
                var cookieContainer = new CookieContainer();

                // Формирование запроса к сервису аутентификации.
                HttpWebRequest request = HttpWebRequest.Create(serverUri + authServiceUri) as HttpWebRequest;
                request.Method = "
POST";
                request.CookieContainer = cookieContainer;
                request.ContentType = "
application/json";
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(authData, 0, authData.Length);
                }
                // Получение ответа от сервера. Если аутентификация прошла успешно, сервер возвратит аутентификационные
                // cookie, которые сохраняются в объекте. В дальнейшем эти cookie будут добавляться в запросы к веб-сервису
                // без повторной аутентификации.
                using (var response = request.GetResponse())
                {
                    if (cookieContainer.Count > 0)
                    {
                        AuthCookie = cookieContainer;
                        return true;
                    }
                }
                return false;
            }
        }

        public static void PostMultipleFiles(string url, string[] files)
        {
            string boundary = "
----------------------------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "
multipart/form-data; boundary=" + boundary;
            httpWebRequest.Method = "
POST";
            httpWebRequest.KeepAlive = true;
            //httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            httpWebRequest.CookieContainer = BPMonlineProcessEngineExample.AuthCookie;
            Stream memStream = new System.IO.MemoryStream();
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("
\r\n--" + boundary + "\r\n");
            string formdataTemplate = "
\r\n--" + boundary + "\r\nContent-Disposition:  form-data; name=\"{0}\";\r\n\r\n{1}"";

Нравится

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

Здравствуйте, Акмаль!
Полагаю, что параметры не передаются или называются не так, как Вы к ним обращаетесь. Вы же добавили параметры "ContactName" и "ContactPhone" в Parameters процесса?
И еще, как-то странно у Вас передача происходит. Вот рабочий примерчик. Параметры передаются в виде строки вида «p1=v1&p2=v2&p3=v3...».

        private const string serverUri = "http://localhost:7207/0/";
        private const string authServiceUtri = "http://localhost:7207/ServiceModel/AuthService.svc/Login";
 
        public static void startProcess(string userName, string userPassword, string processName, string parametersString)
        {
 
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "ServiceModel/ProcessEngineService.svc/"
                                                        + processName + "/Execute?" + parametersString);
            var authRequest = HttpWebRequest.Create(authServiceUtri) as HttpWebRequest;
            authRequest.Method = "POST";
            authRequest.ContentType = "application/json";
            var bpmCookieContainer = new CookieContainer();
            authRequest.CookieContainer = bpmCookieContainer;
            using (var requesrStream = authRequest.GetRequestStream())
            {
                using (var writer = new StreamWriter(requesrStream))
                {
                    writer.Write(@"{
                                ""UserName"":""" + userName + @""",
                                ""UserPassword"":""" + userPassword + @""",
                               ""TimeZoneOffset"":-120,
                                }");
                }
            }
            using (var authResponse = (HttpWebResponse)authRequest.GetResponse())
            {
                request.Method = "POST";
                request.Accept = "application/json";
                request.ContentType = "application/json";
                request.ContentLength = 0;
                request.CookieContainer = bpmCookieContainer;
                var response = (HttpWebResponse)request.GetResponse();
            }
        }

Вот вызов:

 string parametersString = "TaskContact=5178ef17-f882-4fc4-b7d4-8d2d245af929";
 startProcess("Supervisor", "Supervisor", "TestProcess", parametersString);

Андрей, добрый день! Спасибо за ответ.
Скажите, а таким способом можно слать файлы и принимать их в БП?

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

Андрей, здравствуйте!
А как решить проблему слишком длинной строки с параметрами, когда сервер отдает 404? Ссылка точно верная - пробуем с меньшим количеством параметров - все ок.

Здравствуйте!
Стоит Задача интеграции сайта с BPMOnline, c сайта нужно передать много данных в BPMOnline. В бпмке создали процесс который ждет 1 параметр строку (сериализованный json) вызов процесса делаем. если все передавать в Url параметрах то данные приходят, но на сервере стоит ограничение на размер Get запроса. Можно ли в БП передать параметр из тела POST- запроса?

Shamil, так вроде бы POST-запрос и используется. В любом случае, стоит попробовать. Можете перейти по адресу http(s):bpmonline_site/0/ServiceModel/ProcessEngineService.svc/help для получения возможных способов обращения к веб-сервису.

Андрей, да я знаю что можно пост отправить, но параметры из тела поста не передаются в БП

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

Андрей, спасибо.
Я разобрался в БП получаю параметры из формы напрямую с веб-запроса:

var form = HttpContext.Current.Request.Form;
var data = form["Data"];

В принципе такое решение устраивает нас.
Версия 7.2
Но параметры из тела post-запроса в параметры БП так и не передаются.

Вызов делаю так:

public static void SendData(string processName, object data)
        {
            var strData = JsonConvert.SerializeObject(data);
            var url = Path.Combine(serverUri + executeProcessMethodPath + "/"
                                                         + processName + "/Execute");
            using (var client = new CookieWebClient(AuthCookie))
            {
                try
                {
                    client.Encoding = Encoding.UTF8;
                    client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                    var str = client.UploadString(url, "Data=" + strData);
 
                }
                catch (WebException ex)
                {
                    using (var reader = new StreamReader(ex.Response.GetResponseStream()))
                    {
                        var s = reader.ReadToEnd();
                    }
                }
 
 
            }
}

Shamil, я уточню информацию по этой теме, и отпишусь, как только получу результаты.

Столкнулся с проблемой запуска процесса с передачей параметра постом:

public static void startProcess(/*string userName, string userPassword, */string processName, string parametersString)
{
      var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + executeProcessMethodPath + "/"                                                        + processName + "/Execute?" + parametersString);
      try
      {
            request.Method = "POST";
            request.Accept = "application/json";
            request.ContentType = "application/json";
            request.ContentLength = 0;
            request.CookieContainer = AuthCookie;
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                var result = new StreamReader(response.GetResponseStream()).ReadToEnd();
                File.AppendAllText("c:\\emailLogs", "result = " + result + Environment.NewLine);
            }
        }
        catch (Exception ex)
        {
            File.AppendAllText("c:\\emailLogs", ex + Environment.NewLine);
        }
    }
 
    public static bool AddLoan(string data)
    {
        if (!IsAuthentificated)
        {
            return false;
        }
        else startProcess("SiteRequestProcess", "Data=" + data);
 
        return true;
    }

В таком виде сервер возвращает 404, но если передать короткую строку, например

startProcess("SiteRequestProcess", "Data=" + "data");

то тогда процесс запускается. Возможно проблема в длине строки? Есть ли другой способ отправить пост с параметром на сервер?

Добрый день.

К сожалению, передача параметров в потоке метода POST в текущих версиях bpm’online не реализована.
Параметры можно передавать только в URL запроса. При этом существует ряд ограничений на длину URL:

Акмаль, на мой взгляд, ошибка в том, что Вы при формировании POST-запроса параметры записали в адресную строку, что неправильно.
См.
https://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx
http://stackoverflow.com/questions/4015324/http-request-with-post

А в описании методов сервиса написано, что Execute все-таки можно вызвать POST'ом.

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

Добрый день!

Версия Террасофта 3.4. ( ядро 3.4, сервисы 3.3.2)

Бизнес-процесс запускается через автоматический запуск процесса при изменении определенного поля

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

В событии BeforeExecute для первой задачи из бизнес-процесса используется следующий код:
var ProektVisesID = WFGetParamValue(ActionItem.ParentItems.ParentDiagram, 'AutoID');
var ProektVisesDataset = Services.GetSingleItemByUSI('ds_ProektVises');
ApplyDatasetFilter(ProektVisesDataset, 'ID', ProektVisesID, true);
ProektVisesDataset.Open();
var ProektID = ProektVisesDataset.Values('ProektID');
ProektVisesDataset.Close();
WFSetParamValue(ActionItem.ParentItems.ParentDiagram,'ProektID',ProektID);

В параметрах диаграммы заведен параметр ProektID.
Но при создании задачи поле ProektID в карточке задачи остается пустым.

Где нужно прописать связь параметра ProektID и поля ProektID в задаче при автоматическом запуске процесса ( через действие "автоматический запуск процесса") ?

Нравится

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

Здравствуйте.

Вам нужно создать элемент открытия окна, и определить связь между параметром диаграммы и полями данного окна:

1

Добрый день!
У меня бизнес-процесс состоит из нескольких задач, в качестве элементов выбраны блоки типа "задача". Вы предлагаете вместо них использовать элементы открытия окна? Просто у блоков задача есть специфичные характеристики, которые используются в бизнес-процессе.

А у вас в wa_TaskActionScript прописана обработка этого параметра? Если нет, нужно по аналогии с контактом, контрагентом дописать.

Да, прописана.

Код из события BeforeExecute для первой задачи из бизнес-процесса перенесла в обработку события OnStart элемента Start. Параметр стал передаваться

Код из события BeforeExecute для первой задачи из бизнес-процесса перенесла в обработку события OnStart элемента Start. Параметр стал передаваться

Дарья, здравствуйте.

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

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