Доброго времени суток! Коллеги, помогите пожалуйста с переводом запроса SQL на С# для использования в конфигурационном веб-сервисе. Необходимо через запрос к веб-сервису по ИНН контакта получать в ответе перечень Id заявок и Названий их статусов. SQL запрос выглядит так:

 

SELECT a.Id, s.Name
FROM dbo.Application a
INNER JOIN dbo.Contact c ON a.ContactId = c.Id
INNER JOIN dbo.AppStatus s ON a.StatusId = s.Id
WHERE c.INNN='1234567890'

 

Нравится

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

Здравствуйте! В данной статье описано как работать с классом EntitySchemaQuery и как строить пути к колонкам, а в данной статье показано как получить данные из запроса.

Сделал согласно информации в указанных статьях:

        public string UsrGetAppInfoByINN(string INN) {
            // Результат по умолчанию.
            var result = "";
            // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных.
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            // Добавление колонок в запрос.
            esqQuery.AddColumn("Id");
            esqQuery.AddColumn("[AppStatus:Id:StatusId].Name");
            esqQuery.AddColumn("[Contact:Id:ContactId].INN");
               // Фильтрация данных запроса.
            var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esq.Filters.Add(esqFilter);
            // Получение результата запроса.
            string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); 
            // Возвратить результат.
            return result;

При публикации получаю ошибки "The name 'esq' does not exist in current context в строках:   

            var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esq.Filters.Add(esqFilter);

            esq.Filters.Add(esqFilter);

Так у Вас переменная называется esqQuery, а не esq.

Зверев Александр,

заменил esq на esqQuery. Схема публикуется, но на запрос приходит ошибка: 

The server encountered an error processing the request. The exception message is 'Элемент коллекции с именем StatusId не найден'. 

Если убрать эту строку из кода - ругается на следующую ContactId, хотя обе эти колонки есть в таблице Application

        public string UsrGetAppInfoByContactINN(string INN) {
            // Результат по умолчанию.
            var result = "";
            // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных.
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            // Добавление колонок в запрос.
            esqQuery.AddColumn("INN");
            esqQuery.AddColumn("[AppStatus:Id:StatusId].Name");
            esqQuery.AddColumn("[Contact:Id:ContactId].INN");
               // Фильтрация данных запроса.
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esqQuery.Filters.Add(esqFilter);
            // Получение результата запроса.
            string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); 
            // Возвратить результат.
            return result;

Что я делаю не так?

Нужно писать названия полей без Id, см. примеры по ссылке выше.

Зверев Александр,

не понимаю почему без Id, если колонки в таблице так и называются: ContactId, StatusId, но это помогло, спасибо.

 

Правда теперь после отправки запроса - я получаю пустой ответ на запрос:

{"UsrGetAppInfoByContactINN":""}

 

Александр О,

здравствуйте! Далее Вам необходимо получить коллекцию

var collection = esqQuery.GetEntityCollection(UserConnection);
if(collection.Count > 0)
{
  foreach(var entity in collection)
  {
     var name = entity.GetTypedColumnValue<string>("Name");
  }
}

 Примерно так.

Только еще один момент, Вам необходимо получить названия колонок  в esqQuery, что бы потом можно было выбирать из коллекции по имени.

var appColName = esqQuery.AddColumn("[AppStatus:Id:StatusId].Name").Name;
 
var collection = esqQuery.GetEntityCollection(UserConnection);
if(collection.Count > 0)
{
  foreach(var entity in collection)
  {
     var name = entity.GetTypedColumnValue<string>(appColName);
  }
}

 

Александр О пишет:
не понимаю почему без Id, если колонки в таблице так и называются

Оно в этом случае не пишется, при генерации запроса подставляется автоматически.

Нигрескул Алексей,

с помощью Ваших рекомендаций и дополнительных танцев с бубном схема видоизменилась на:

        public string UsrGetAppInfoByContactSSN(string ContactINN) {
            var result = "";
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            var appColApplicationId = esqQuery.AddColumn("Id").Name;
            var appColStatus = esqQuery.AddColumn("Status.Name").Name;
            var appColINN = esqQuery.AddColumn("Contact.INN").Name;
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN);
            esqQuery.Filters.Add(esqFilter);
            var collection = esqQuery.GetEntityCollection(UserConnection);
                if(collection.Count > 0)
                    {
                      foreach(var entity in collection)
                        {
            var name = ("ApplicationId:").ToString() + entity.GetTypedColumnValue<string>(appColApplicationId)
                   +(", Status:").ToString() + entity.GetTypedColumnValue<string>(appColStatus)
                   +(", INN:").ToString() + entity.GetTypedColumnValue<string>(appColINN);
            return name;
                        }
                     }
            return result;

 В результате в ответ на запрос получаю:

{"UsrGetAppInfoByContactSSNResult":"ApplicationId:cee41684-295b-4384-8dfb-1fa3fdd835cc, Status:Підтверджена, INN:4562378478"}

Но это только одна запись.

Что нужно изменить в схеме чтобы в ответе приходили все найденные записи? Например так:

{"UsrGetAppInfoByContactSSNResult":
"ApplicationId:a913e1c5-6e83-428c-b095-0cf1b3aca5bf, Status:Підтверджена, INN:4562378478"
"ApplicationId:cee41684-295b-438e-8dfb-1fa3fdd835cc, Status:В роботі, INN:4562378478"
"ApplicationId:47a7a0be-4c21-430f-9da9-7d1b658cff92, Status:Відмовлено, INN:4562378478"
}

 

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

Всем доброго времени суток!

Столкнулся с такой проблемой, валятся ошибки при использовании ATF.Repository объектной модели и выгрузке данных в список:
 

[Schema("Account")]
    public class Account : BaseModel
    {       
        
        [SchemaProperty("Name")]
        public string Name { get; set; }        
        
        [DetailProperty("Account")]
        public virtual List<AccountWorkingTime> WorkingTimes { get; set; }
    }

[Schema("AbWorkingTimeStation")]
    public class AccountWorkingTime : BaseModel
    {
        [SchemaProperty("Account")]
        public Guid AccountId { get; set; }
        
        [LookupProperty("DayOfWeek")]
        public virtual DayOfWeek DayOfWeek { get; set; }
        
        [SchemaProperty("From")]
        public DateTime From { get; set; }
        
        [SchemaProperty("To")]
        public DateTime To { get; set; }

    }

namespace PlatformIntegration.Files.cs
{
    [DefaultBinding(typeof(IAccountAdapter))]
    public class AccountAdapter : IAccountAdapter
    {
        public UserConnection UserConnection { get; set; }

        public AccountAdapter(UserConnection userConnection)
        {
            UserConnection = userConnection;
        }
        private IRepository _repository;

        private IRepository Repository
        {
            get => _repository ??= new Repository
                {UserConnection = UserConnection, UseAdminRight = false};
            set => _repository = value;
        }

        public Models.Account GetAccountById(Guid id)
        {
            var account = Repository.GetItem<Models.Account>(id);
            return account;
        }        
    }
}

При отработке метода GetAccountById - вылазят ошибки https://prnt.sc/uh1zso

Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Error getting value from 'WorkingTimes' on 'Castle.Proxies.AccountProxy'.
Newtonsoft.Json.JsonSerializationException: Error getting value from 'WorkingTimes' on 'Castle.Proxies.AccountProxy'. ---> System.Reflection.TargetInvocationException: Адресат вызова создал исключение. ---> System.InvalidCastException: Объект должен реализовывать интерфейс IConvertible.
   в System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   в ATF.Repository.Repository.FillPropertyValue[T](T model, PropertyInfo propertyInfo, Object value)
   в ATF.Repository.Repository.FillPropertyValues[T](T model, IDictionary`2 values)
   в ATF.Repository.Repository.CreateItem[T](IDictionary`2 values)
   в ATF.Repository.Repository.LoadModelByValues[T](IDictionary`2 values)
   в ATF.Repository.Repository.<>c__DisplayClass64_0`1.<GetItems>b__0(IDictionary`2 recordValues)
   в System.Collections.Generic.List`1.ForEach(Action`1 action)
   в ATF.Repository.Repository.GetItems[T](String filterPropertyName, Guid filterValue)
   --- Конец трассировки внутреннего стека исключений ---
   в System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   в System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   в System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   в ATF.Repository.Repository.FillDetailValue[T](T model, ModelItem detail)
   в ATF.Repository.Builder.InstanceProxyHelper`1.FillProperty(IInvocation invocation, PropertyInfo property)
   в ATF.Repository.Builder.InstanceProxyHelper`1.InternalGet(IInvocation invocation, PropertyInfo property)
   в ATF.Repository.Builder.InstanceProxyHelper`1.Intercept(IInvocation invocation)
   в Castle.DynamicProxy.AbstractInvocation.Proceed()
   в Castle.Proxies.AccountProxy.get_WorkingTimes()
   в GetWorkingTimes(Object )
   в Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
   --- Конец трассировки внутреннего стека исключений ---
   в Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   в Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   в Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   в Newtonsoft.Json.JsonConvert.SerializeObject(Object value)
   в AutobookingPlatformIntegration.AccountIntegrationService.GetAccountById(Guid id)
   в SyncInvokeGetAccountById(Object , Object[] , Object[] )
   в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
   в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
 

Кто нибудь сталкивался с таким поведением?

 

 

Нравится

3 комментария

Нашел в чем проблема. Не может десерелизовать в модель колонку с типом Время - https://prnt.sc/uhpw7o в DateTime. Кто работал с данным репозиторием знает решение данной проблемы?

Алексей, не вижу никаких упоминаний о ATF.Repository, кроме этой темы. Речь о тех ATF, которые сделали «.NET Core connector»? Там указан адрес на GitHub для связи с разработчиками. Возможно, они подскажут по этому механизму.

Зверев Александр,

да, эти, писал и на почту, правда по другому вопросу, по текущему на гитхабе- пока ответа не получал

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

Задача: округлять дробную часть десятичного числа вверх.

Нашёл статью с методом на Microsoft https://docs.microsoft.com/en-us/dotnet/api/system.midpointrounding?vie… 

 

В БП пробую применять формулу Decimal.Round(([#Исходное дробное число#]), 1, MidpointRounding.AwayFromZero) - ругается, что "Допущена ошибка в формуле: Параметр "MidpointRounding" не найден.]."

При этом, если не использовать MidpointRounding, а просто указывать количество знаков после запятой Decimal.Round(([#Исходное дробное число#]), 1) - то формулу принимает и пересчёт ведёт, но по правилам округления, а не в бОльшую сторону, как мне нужно.

 

Может быть кто-то сталкивался с такой же задачей? Как решали?

Нравится

1 комментарий

Сергей, в отличие от старого движка процессов, в котором можно было указать в элементе-формуле или условии произвольный фрагмент C#-кода, в нынешнем, интерпретируемом, работа с формулами может не поддерживать все особенности функций от Microsoft.

 

Как обходной вариант, можно создать блок-скрипт, где считать значение из параметра, вычислить округление нужным способом и записать в другой.

decimal positiveValue = Get<decimal>("ProcessSchemaParameterPositiveValue");
decimal result = Math.Round(positiveValue, 1, MidpointRounding.ToEven);
Set<decimal>("ProcessSchemaParameterResult", result);
return true;

А если таких вычислений у Вас в процессах много, можно создать свой UserTask с параметрами, куда передавать значения и способ округления.

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

Добрый день! При формировании такой структуры получаю NotSupportedException(внутри None):

 

{
    "QueryType": 1,
    "IsForceUpdate": false,
    "IsUpsert": false,
    "Filters": {
        "RootSchemaName": null,
        "FilterType": 0,
        "ComparisonType": 0,
        "LogicalOperation": 0,
        "IsNull": true,
        "IsEnabled": true,
        "IsNot": false,
        "SubFilters": null,
        "Items": {
            "primaryColumnFilter": {
                "FilterType": 1,
                "ComparisonType": 3,
                "LogicalOperation": 0,
                "IsNull": true,
                "IsEnabled": true,
                "IsNot": false,
                "SubFilters": null,
                "Items": null,
                "LeftExpression": {
                    "ExpressionType": 1,
                    "ColumnPath": null,
                    "Parameter": null,
                    "FunctionType": 1,
                    "MacrosType": 34,
                    "FunctionArgument": null,
                    "DatePartType": 0,
                    "AggregationType": 0,
                    "AggregationEvalType": 0,
                    "SubFilters": null
                },
                "RightExpression": {
                    "ExpressionType": 2,
                    "ColumnPath": null,
                    "Parameter": {
                        "DataValueType": 0,
                        "Value": "310ef086-1e11-4290-9c4e-90e78df4d69a",
                        "ArrayValue": null,
                        "ShouldSkipConvertion": false
                    },
                    "FunctionType": 0,
                    "MacrosType": 0,
                    "FunctionArgument": null,
                    "DatePartType": 0,
                    "AggregationType": 0,
                    "AggregationEvalType": 0,
                    "SubFilters": null
                },
                "RightExpressions": null,
                "RightLessExpression": null,
                "RightGreaterExpression": null,
                "TrimDateTimeParameterToDate": false,
                "Key": null,
                "IsAggregative": false,
                "LeftExpressionCaption": null,
                "ReferenceSchemaName": null
            }
        },
        "LeftExpression": null,
        "RightExpression": {
            "ExpressionType": 2,
            "ColumnPath": null,
            "Parameter": {
                "DataValueType": 0,
                "Value": "310ef086-1e11-4290-9c4e-90e78df4d69a",
                "ArrayValue": null,
                "ShouldSkipConvertion": false
            },
            "FunctionType": 0,
            "MacrosType": 0,
            "FunctionArgument": null,
            "DatePartType": 0,
            "AggregationType": 0,
            "AggregationEvalType": 0,
            "SubFilters": null
        },
        "RightExpressions": null,
        "RightLessExpression": null,
        "RightGreaterExpression": null,
        "TrimDateTimeParameterToDate": false,
        "Key": null,
        "IsAggregative": false,
        "LeftExpressionCaption": null,
        "ReferenceSchemaName": null
    },
    "QueryId": null,
    "QueryKind": 0,
    "ColumnValues": {
        "Items": {
            "UsrName": {
                "ExpressionType": 2,
                "ColumnPath": null,
                "Parameter": {
                    "DataValueType": 1,
                    "Value": "name96ae3de9-f90f-46a9-8b57-afeebedd6499",
                    "ArrayValue": null,
                    "ShouldSkipConvertion": false
                },
                "FunctionType": 0,
                "MacrosType": 0,
                "FunctionArgument": null,
                "DatePartType": 0,
                "AggregationType": 0,
                "AggregationEvalType": 0,
                "SubFilters": null
            },
            "UsrSalesFunnelStage": {
                "ExpressionType": 2,
                "ColumnPath": null,
                "Parameter": {
                    "DataValueType": 10,
                    "Value": "d136a6533-ee2b-4b4b-9366-ffe375568691",
                    "ArrayValue": null,
                    "ShouldSkipConvertion": false
                },
                "FunctionType": 0,
                "MacrosType": 0,
                "FunctionArgument": null,
                "DatePartType": 0,
                "AggregationType": 0,
                "AggregationEvalType": 0,
                "SubFilters": null
            },
            "UsrPartnerType": {
                "ExpressionType": 2,
                "ColumnPath": null,
                "Parameter": {
                    "DataValueType": 10,
                    "Value": "4397d6d7-0b95-43e6-9261-d01df863724f",
                    "ArrayValue": null,
                    "ShouldSkipConvertion": false
                },
                "FunctionType": 0,
                "MacrosType": 0,
                "FunctionArgument": null,
                "DatePartType": 0,
                "AggregationType": 0,
                "AggregationEvalType": 0,
                "SubFilters": null
            },
            "Id": {
                "ExpressionType": 2,
                "ColumnPath": null,
                "Parameter": {
                    "DataValueType": 0,
                    "Value": "310ef086-1e11-4290-9c4e-90e78df4d69a",
                    "ArrayValue": null,
                    "ShouldSkipConvertion": false
                },
                "FunctionType": 0,
                "MacrosType": 0,
                "FunctionArgument": null,
                "DatePartType": 0,
                "AggregationType": 0,
                "AggregationEvalType": 0,
                "SubFilters": null
            }
        }
    },
    "RootSchemaName": "UsrPartnersTest",
    "IncludeProcessExecutionData": true
}

все происходит в облаке

Нравится

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

Евгений, а что это за запрос был? Его формировали программно в коде или сгенерировался при работе с клиентской ESQ?

Смущает пустой RootSchemaName сверху, дважды переданный RightExpression с Guid (и третий раз он же как колонка). Я для пробы поменял значение в какой-то карточке, сохранил, у меня запрос к сервису совсем не такой вышел.

 

Зверев Александр,

это BaseQuery сериализованный 

Terrasoft.Nui.ServiceModel.DataContract.BaseQuery, я заполнил структуру так (т к в документации нет примера):
var query = new UpdateQuery
            {
                IncludeProcessExecutionData = true,
                RootSchemaName = schemaName,
                ColumnValues = new ColumnValues
                {
                    Items = new Dictionary<string, ColumnExpression>()
                }
            };
 
 query.Filters = new Filters
            {
                RightExpression = new BaseExpression
                {
                    ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                    Parameter = new Terrasoft.Nui.ServiceModel.DataContract.Parameter
                    {
                        DataValueType = DataValueType.Guid,
                        Value = id
                    }
                },
                Items = new Dictionary<string, Filter>
                {
                    {
                        "primaryColumnFilter", new Filter()
                        {
                            FilterType = FilterType.CompareFilter,
                            ComparisonType = FilterComparisonType.Equal,
                            IsEnabled = true,
                            LeftExpression = new BaseExpression
                            {
                                FunctionType = FunctionType.Macros,
                                ExpressionType = EntitySchemaQueryExpressionType.Function,
                                MacrosType = (EntitySchemaQueryMacrosType) 34,
                            },
                            RightExpression = new ColumnExpression
                            {
                                ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                                Parameter = new Terrasoft.Nui.ServiceModel.DataContract.Parameter
                                {
                                    DataValueType = DataValueType.Guid,
                                    Value = id
                                }
                            }
                        }
                    }
                }
            };
 
            foreach (var parameterPair in operation.Parameters)
            {
                var columnExpression = new ColumnExpression
                {
                    ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                    Parameter = new Terrasoft.Nui.ServiceModel.DataContract.Parameter
                    {
                        Value = parameterPair.Value.Value,
                        DataValueType = parameterPair.Value.Type,
                    }
                };
 
                query.ColumnValues.Items.Add(parameterPair.Value.Name, columnExpression);
            }

 

 

 

 

 

 

 

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

Вы делаете внешний софт на C#, работающий с сервисами системы?

Документация по запросам обновления и фильтрам есть в академии.

Если же делаете внутри скриптов БП, то можно просто использовать класс Update.

Посмотреть структуру правильного запроса можно, проделав в интерфейсе аналогичное и записав, что ушло на сервер.

Зверев Александр,

дело в том что я ориентировался как раз на запросы внутри самой crm. да, я реализую интеграцию с другими сервисами. Документация есть, но именно в обновлении примеров нет. И мне все-таки каким-то образом нужно понять что именно не так с запросом

 

В самой системе при обновлении записи получается совсем не такой запрос, как у Вас. Например, меняю индекс в адресе контакта:

{
   "rootSchemaName":"ContactAddress",
   "operationType":2,
   "includeProcessExecutionData":true,
   "filters":{
      "items":{
         "primaryColumnFilter":{
            "filterType":1,
            "comparisonType":3,
            "isEnabled":true,
            "trimDateTimeParameterToDate":false,
            "leftExpression":{
               "expressionType":1,
               "functionType":1,
               "macrosType":34
            },
            "rightExpression":{
               "expressionType":2,
               "parameter":{
                  "dataValueType":0,
                  "value":"9ce6c7ce-5ae4-df11-971b-001d60e938c6"
               }
            }
         }
      },
      "logicalOperation":0,
      "isEnabled":true,
      "filterType":6
   },
   "columnValues":{
      "items":{
         "Zip":{
            "expressionType":2,
            "parameter":{
               "dataValueType":1,
               "value":"105122"
            }
         }
      }
   },
   "isForceUpdate":false
}

 

Зверев Александр,

остальные поля просто выходят в результате стерилизации BaseQuery от Terrasoft. Если его нужно использовать как-то иначе - дайте знать. Не хочется делать свой класс, учитывая что в библиотеке уже есть готовый

Горянин Евгений Юрьевич пишет:
остальные поля просто выходят в результате стерилизации BaseQuery от Terrasoft.

Но Вы же сами написали, что заполняете так. Зачем там два раза  RightExpression и подобное?

 

Может, лучше интеграцию по OData, как тут:

ИЗМЕНЕНИЕ СУЩЕСТВУЮЩЕГО ОБЪЕКТА

public static void UpdateCreatioEntityByOdatetWcfExample()
{
    // Создание контекста приложения Creatio.
    var context = new Creatio(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);
    // Сохранение изменений данных в Creatio одним запросом.
    var responces = context.SaveChanges(SaveChangesOptions.Batch);
}

 

Зверев Александр,

ну переделывать общий процесс под OData теперь уже нет возможности. с Select и Insert проблем не возникло, нужен какой-то пример на c# с использованием Update

На C# с запросами к данным работают либо через OData (во внешнем софте) либо внутри конфигурации системы через классы EntitySchemaQuery или Select/Insert/Update/Delete.

 

В Вашем случае это какой-то ещё один вариант. Если разобрались с Select и Insert, наверное и Update можно, чтобы в итоге к сервису уходил JSON, аналогичный отправляемому из браузера.

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

При отправке запроса к удалённому серверу 
Получаю ошибку:
 The request was aborted: Could not create SSL/TLS secure channel.

Нравится

3 комментария

Добрый день, Игорь.

Обратите внимание сюда.

Мотков Илья,

Спасибо, но это не помогло.
У меня есть подозрение, что ошибка происходит на этапе обращения из клиентской части к web-сервису  bpmonline по ссылке
Мой кейс:
Есть кнопка "прослушать"  в р. Звонки. При отправке запроса при клике на кнопку нельзя передать данные для аутентификации.
Поэтому ссылка для кнопки формируется к web-сервису bpmonline, который в свою очередь отправляет авторизованный запрос к удалённому серверу на получение потока.
CallStack ошибки не отображает вызов метода, который отправляет запрос к удалённому серверу, значит делаю вывод, что ошибка происходит на этапе вызова web-сервиса bpmonline.
Как обойти данную, ошибку ума не приложу.

 

Не видя, кто именно выдал ошибку, сложно сказать наверняка. Если сервер 7.Х, то более подробно будет в логах, если пришла от сервера телефонии, это сообщение будет видно при мониторинге HTTP-траффика от него.

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

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

Подскажите как можно из Бизнес процесса обратится к C# методу?

Нравится

2 комментария

Добрый день! Здесь -  http://prntscr.com/qr8kpl подключаем нам нужное пространство имен, затем объявляем экземпляр класса и вызываем метод - http://prntscr.com/qr8lqh 

Благодарю

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

Подскажите как можно в C# сделать Serialize в json объект класса

public class ImportCreatioServiceCaseColumns
{
	[JsonPropertyName("idNumber")]
	public string IdNumber { get; set; }
	[JsonPropertyName("typeCase1Name")]
	public string TypeCase0Name { get; set; }
}
public class ImportCreatioProcessCaseColumnsOut
{
	[JsonPropertyName("schemaName")]
	public string BusinessProcessName { get; set; }
	[JsonPropertyName("parameterValues")]
	public ImportCreatioServiceCaseColumns ImportCreatioServiceCaseColumns { get; set; }

}

и привести его к виду 

{
	"schemaName":"KtImportCaseTransferTableInBPMTest",
	"parameterValues":
	[
		{"name":"idNumber","value":"80001019"},
		{"name":"typeCase1Name","value":"Алматы"}
	]
}

?

Это нужно что бы передать body в микровервис для запуска бизнес-процесса с параметрами POST методом.

Нравится

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

Можно подключитье  Json.NET он уже включен в коробке. Подробнее об использовании смотрите https://www.newtonsoft.com/json

 

Как то так

 

sing System;
using Newtonsoft.Json;
 
namespace JsonPrettyPrint
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Product product = new Product
                {
                    Name = "Apple",
                    Expiry = new DateTime(2008, 12, 28),
                    Price = 3.99M,
                    Sizes = new[] { "Small", "Medium", "Large" }
                };
 
            string json = JsonConvert.SerializeObject(product, Formatting.Indented);
            Console.WriteLine(json);
 
            Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
        }
    }
 
    internal class Product
    {
        public String[] Sizes { get; set; }
        public decimal Price { get; set; }
        public DateTime Expiry { get; set; }
        public string Name { get; set; }
    }
}

 

Не работает так как нужен именно такой формат, уже пробовал как Вы советуете 

Григорий Чех пишет:
{"name":"idNumber","value":"80001019"},

Похожий формат обсуждают тут.

 

Зверев Александр пишет:

Похожий формат обсуждают тут.

А Вы пробовали вызывать бизнес-процесс из другого приложения через post вызов передавая параметры через тело запроса? 

Александр, см. тут.

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

Всем доброго времени суток! 

Столкнулся со следующей проблемой, у нас в системе были кастомные Excel отчеты, выгружались посредствам библиотеки ClosedXml, и все работало, но с версии 7.14 перестало работать. Высыпаются ошибки в зависимостях:

Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Метод не найден: "System.IO.Packaging.PackageProperties DocumentFormat.OpenXml.Packaging.OpenXmlPackage.get_PackageProperties()".
System.MissingMethodException: Метод не найден: "System.IO.Packaging.PackageProperties DocumentFormat.OpenXml.Packaging.OpenXmlPackage.get_PackageProperties()

Пробовал устанавливать разные версии библиотеки не помогло.

Кто работал с библиотекой ClosedXml в bpm'online, может знает какую версию использовать?

Текущая версия crm 7.14.4 

заранее благодарен.

Нравится

4 комментария
Лучший ответ

Столкнулся, к сожалению. пришлось все переписывать... В ClosedXML используются библиотеки DocumentFormat.OpenXml, в версии 7.14 видимо обновили версию библиотеки/зависимых библиотек и все. Мучался часа 3 с зависимостями, потом плюнул и переписал на OpenXml генерацию xls

Столкнулся, к сожалению. пришлось все переписывать... В ClosedXML используются библиотеки DocumentFormat.OpenXml, в версии 7.14 видимо обновили версию библиотеки/зависимых библиотек и все. Мучался часа 3 с зависимостями, потом плюнул и переписал на OpenXml генерацию xls

А что говорит по этому вопросу служба поддержки? Что они рекомендуют?

Алла Савельева,

Здравствуйте! Пока ничего. Анализирует предоставленный мною лог.

Нигрескул Алексей,

Поделитесь потом здесь ответом, очень интересует данная тема. Спасибо)

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

Всем доброго времени суток! Столкнулся со следующей проблемой. Есть БП который запускается после изменения записи, в нем есть скрипт-таск в котором определяется заголовок Origin - System.Web.HttpContext.Current.Request.Headers["Origin"], если изменение производились через карточку записи то заголовок присутствовал и процесс шел по одной ветке, если же изменение произошло кодом через интеграцию, то заголовок был пустой. Это работало до недавнего времени, сейчас же System.Web.HttpContext.Current == null.

Кто нибудь с таким сталкивался?

Нравится

2 комментария

Разобрался, в настройке начального сигнала стояло выполнять след. эл-ты в фоне. Из-за этого не читалось.

Лучше вообще не завязываться на такие недокументированные возможности, а сразу сделать зримое различие в данных, приходящих из интерфейса или по интеграции. Например, добавить в объект дополнительное поле, логическое или справочник и при работе интеграции его заполнять. Или просто запускать интеграцию под отдельным пользователем и смотреть значение ModifiedById.

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

Всем доброго времени суток. Подскажите есть ли возможность у bpm'online интегрироваться с RabbitMQ, а именно подписываться на сообщения?

Благодарю.

Нравится

1 комментарий

Как минимум, в механизме глобального поиска он используется. Нужно смотреть документацию по этому ПО, как устроены стандартные библиотеки для взаимодействия с ним, есть ли они под JS и C# и можно ли ими воспользоваться в конфигурации bpm'online.

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