Запуск процессов извне. Передача параметров.

Добрый день! Возникла проблема с передачей в БП параметров при использовании 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'ом.

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