Есть необходимость отправлять динамические структуры как в js, к примеру через тип JObject, но получаем 500 когда пробуем в веб-сервисе вернуть данный тип.



Как сделать что-то типо такого: 

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
}

 

.net core

Нравится

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

Стас, добрый день!

Для сериализации/десериализации вы можете в сервисе использовать либу Newtonsoft.

Для этого сперва нужно добавить следующие using:

using Newtonsoft.Json;

using Newtonsoft.Json.Linq;

После чего в методе сервиса вызвать:

var content = JsonConvert.SerializeObject(objectToSerialize);

Хочется что бы это был стандартный сериализатор, а не возвращать строку которая ещё раз будет сериализирована стандартным .net  сериализатором. 

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

Нужно для правильной возвращаемой структуры типов CompositeObject, без Key/Value, а нативно - {"key": value}

 

Нравится

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

нативно, имеешь ввиду через jobject? или имеешь ввиду задать column key кастомный, если оно, то аннотация(не помню как с# это называется) jsonproperty может помочь наверное

[JsonProperty("Ref_Key", NullValueHandling = NullValueHandling.Ignore)]
или имеешь ввиду избавиться от имени метода в возвращаемом объекте?
тогда наверное стоит юзать это BodyStyle = WebMessageBodyStyle.Bare в аннотации

 [OperationContract]

        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json,RequestFormat =

        WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]

в этом случае, тебе не надо будет писать название объекта передаваемого в тело метода и возвращаемом тоже не будет его в названии

типа так user:{name:"3213"} станет {name:"3232"}

 

Dima Avdoshin,

можно и через JObject главное что бы можно динамично составлять структуры данных. попытка вернуть JObject вообще дает 500 ошибку, как я понимаю дефолтный сериализатор не умеет в JObject.

 

задача сама в том что возвращать сразу красиво, а не через строку  через - JsonConvert.SerializeObject.



сейчас на такой код в сервисе: 

 

        [OperationContract]

        [WebInvoke(Method = "GET", 

            RequestFormat = WebMessageFormat.Json, 

            BodyStyle = WebMessageBodyStyle.Wrapped,

            ResponseFormat = WebMessageFormat.Json,

            UriTemplate = "/ping/{s}")]

            [return: MessageParameter(Name = "data")]

        public object Pong(string s) {

            var res = new CompositeObject();

            res.Add("ping", "pong");

            return res;

        }

 

получаем такой ответ: 

 

{

"data": [

{

"Key": "ping",

"Value": "pong"

}

]

}

 

а надо: {"data":  [{ "ping": "pong"}]} или если короче, то что возвращает JsonConvert.

Стас Гаврилюк,

не решал такого рода задачу, но вот что нагуглил https://stackoverflow.com/questions/17806811/dynamic-objects-in-wcf-not…

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

Подскажите как можно в 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 вызов передавая параметры через тело запроса? 

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

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

Добрый день.

Есть самописный модуль, в параметры которого необходимо передать filterGroup для выполнения фильтрации внутри модуля.

Пробовал передать просто объект filterGroup - параметр с объектом не передается в модуль.

Пробовал передать 

filterGroup.serialize() 

- при десериализации строки получаю совершенно другую структуру объекта

Terrasoft.deserialize(filterGroup)

При добавлении этого фильтра в ESQ-запрос

происходит ошибка:

"Uncaught TypeError: a.on is not a function"

Подскажите, как корректно:

1. передать объект в параметры модуль?

2. провести сериализацию группы фильтров с последующим 



 

Нравится

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

ага. упирался уже в данный нюанс. Не могу найти пример с проекта, но фишка в serializationInfo. Вот пример из дефолтной конфигурации:

var serializationInfo = sectionFilters.getDefSerializationInfo();
serializationInfo.serializeFilterManagerInfo = true;
var deserializedFilters = Terrasoft.deserialize(sectionFilters.serialize(serializationInfo));

Попробуйте сериализовать. Прокинуть в модуль строкой, а в модуле десериализовать.



В консоли по быстрому накидал. Посмотрите, как различаются 2 результата десериализации (в моём примере v=Terrasoft.createFilterGroup()):

Варфоломеев Данила,

Огромное спасибо! Всё получилось.

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

Здравствуйте! Помогите пожалуйста решить задачу программной загрузки сервисов из файлов на диске в базу, на C#.
Выполняю следующий метод

//connector - соединение с базой, path - путь к сервису wnd_ContactEdit
private static void LoadAndSaveService(Connector connector, string path)
{
 
   var service = (TSObjectLibrary.IService)connector.Services.GetNewItemByUSI("wnd_ContactEdit");

   var xmlStrogare = new TSObjectLibrary.XMLStorage();
   xmlStrogare.LoadFromFile(path);
   service.Deserialize(xmlStrogare.RootNode);
   connector.Services.SaveItem(service, SaveDatabaseObjectActionEnum.sdoaSave);
}

И возникает ошибка в строчке service.Deserialize(xmlStrogare.RootNode):
Object doesn't support interface {76218379-EDB8-43D5-A106-93A32C30612A} ({76218379-EDB8-43D5-A106-93A32C30612A})
Причем при выполнении того же кода в JavaScript в администраторе все нормально десериализуется и сервис сохраняется.
Версия бинарников 3.3.2.194

Нравится

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

Алексей, можете пожалуйста показать код JScript в Администраторе

Метод сериализации в VisualStudio у меня тоже не работал.(Такая же ошибка Object doesn't support interface)

Рабочий код в администраторе Terrasoft, но он заменяет окно редактирования на пустое окно с заголовком

function Main() {
	var service = Connector.Services.GetNewItemByUSI("wnd_ContactEdit");
   	var XMLStorage = new ActiveXObject('TSObjectLibrary.XMLStorage');
	XMLStorage.InitRootNode("Service");
	XMLStorage.RootNode.SetAttributeAsStr("WindowCaption", "Заголовок окна", "");
	service.Deserialize(XMLStorage.RootNode);
    Connector.Services.SaveItem(service, 1);
}

Попытка загрузить тем же способом сервис, выгруженный вручную с помощью "Сохранить в файл" из администратора (приложенный во вложении), не привел к успеху.

function Main() {
	var service = Connector.Services.GetNewItemByUSI("wnd_ContactEdit");
   	var XMLStorage = new ActiveXObject('TSObjectLibrary.XMLStorage');
        XMLStorage.LoadFromFile("C:\\wnd_ContactEdit.xml");
	service.Deserialize(XMLStorage.RootNode);
        Connector.Services.SaveItem(service, 1);
}

На строчке service.Deserialize(XMLStorage.RootNode); выскочила ошибка
TSDskWindowLibrary.DskWindow: Член группы не найден

Здравствуйте Алексей
Воспроизвели данную проблему, передали вопрос в отдел разработки. Я вас проинформирую про решение данного вопроса

Здравствуйте всем
Проблема возникает из-за того, что Вы не корректно объявляете переменные.
Ниже приведен абсолютно работоспособный код:

public bool SaveServiceToDatabase(Connector connector, string serviceFilePath)
        {
            XMLStorage xmlStorage = new XMLStorageClass();
            xmlStorage.LoadFromFile(serviceFilePath);
            string serviceTypeCode;
            string serviceUSI;
            try
            {
                serviceTypeCode = xmlStorage.RootNode.GetAttributeAsStr("ServiceTypeCode", "");
                serviceUSI = xmlStorage.RootNode.GetAttributeAsStr("USI", "");
            }
            catch
            {
                return false;
            }
            ServiceInfo serviceInfo =
                   (TSObjectLibrary.ServiceInfo)сonnector.Services.get_InformationsByUSI(serviceUSI);
            if (serviceInfo != null)
            {
                connector.Services.DeleteItem(serviceUSI, SaveDatabaseObjectActionEnum.sdoaSave);
            }
            Service service = (TSObjectLibrary.Service)connector.Services.CreateItem(serviceTypeCode);
            service.Deserialize(xmlStorage.RootNode);
            connector.Services.SaveItem(service, SaveDatabaseObjectActionEnum.sdoaSave);
            return true;
        }

Также, при работе с загрузкой сервисов следует учесть, что если сервис уже существует, то при Deserialize (его же xml файл) он начнет выдавать ошибки типа "Component named btnOk already exist". Таким образом, в приведенном выше коде делается проверка на существование сервиса и последующего его удаления.

Большое спасибо за помощь!
Код действительно рабочий!

Единственное что хотелось бы добавить, что если мы сохраняем сервис таблицы, то в строчке

connector.Services.DeleteItem(serviceUSI, SaveDatabaseObjectActionEnum.sdoaSave);

происходит удаление таблицы из базы вместе со всеми данными, что недопустимо.
Конкретно у меня, на этой строчке вылетела ошибка связанная с ForeignKey.

Действительно не нужно удалять сервис, нужно создавать новый, в него все десериализировать и сохранить. Вот код:

public bool SaveServiceToDatabase(Connector connector, string serviceFilePath)
        {
            XMLStorage xmlStorage = new XMLStorageClass();
            xmlStorage.LoadFromFile(serviceFilePath);
            string serviceTypeCode;
            try
            {
                serviceTypeCode = xmlStorage.RootNode.GetAttributeAsStr("ServiceTypeCode", "");
            }
            catch
            {
                return false;
            }
            Service service = (TSObjectLibrary.Service)connector.Services.CreateItem(serviceTypeCode);
            service.Deserialize(xmlStorage.RootNode);
            connector.Services.SaveItem(service, SaveDatabaseObjectActionEnum.sdoaSave);
            return true;
        }
Показать все комментарии