С#, json сериализует список в списке без квадратных скобок

Для интеграции с API мне нужен C# для вывода следующего json:

"fields": {  
    "name1": {  
        "key1": "value1",
        "key2": "value2"
    },
    "name2": {  
        "key3": "value3",
        "key4": "value4"
    },
    "etc..."
}

Я не понимаю, как это настроить. В настоящее время я использую класс, который затем сериализую: JsonConvert.SerializeObject(document).

Я пробовал следующий код:

public class Fields
{
    public string Name { get; internal set; }
         
    public Field myField { get; internal set; }

    public class Field
    {
        public string Value { get; internal set; }

        public string Key { get; internal set; }

        public Field(string value, string key)
        {
            Value = value;
            Key = key;
        }
    }

    public Fields(string name, Field myField)
    {
        Name = name;
        this.myField = myField;
    }
}
List<Fields> myFields = new List<Fields>();

foreach (var field in recipient.Fields)
    {
        myFields.Add(new Fields(field, new Fields.Field(name, value)));
    }

document.Fields = myFields;

Но это приводит к:

"fields": [
    {
      "Name": "name1",
      "myField": {
        "key1": "value1",
        "key2": "value2"
      }
    },
    {
      "Name": "name1",
      "myField": {
        "key3": "value3",
        "key4": "value4"
      }
    }
]

Квадратные скобки вокруг набора полей должны быть удалены, а там, где написано «myField», его следует заменить на переменную «name1», «name2» и т. д. Обновлено: я ошибся, игнорируйте следующую часть. Имена могут повторяться, комбинация имени и второй переменной должна быть уникальной. Я мог бы вручную создать правильную строку с заданными переменными, но я чувствую, что должен быть лучший, "правильный" способ добиться этого.

Редактировать: рабочий пример

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

György Kőszeg 23.02.2023 11:20

Добро пожаловать в StackOverflow! Не могли бы вы поделиться с нами определением исходного объекта с некоторыми примерами данных? Мы могли бы помочь вам лучше, если бы вы поделились с нами минимально воспроизводимым примером

Peter Csala 23.02.2023 12:38
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
1
2
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать Dictionary<string, Dictionary<string, string>> и создать модель с такой структурой:

public class Fields
{
    public Dictionary<string, Dictionary<string, string>> Items { get; set; }
}

Когда словарь сериализуется в JSON, ключи используются как имена свойств, а значения используются как значения свойств. Итак, чтобы воспроизвести вашу структуру JSON в коде, вам нужно инициализировать модель следующим образом:

var fields = new Fields();

var item1 = new Dictionary<string, string>()
{
    ["key1"] = "value1",
    ["key2"] = "value2"
};

var item2 = new Dictionary<string, string>()
{
    ["key3"] = "value3",
    ["key4"] = "value4"
};

fields.Items = new Dictionary<string, Dictionary<string, string>>()
{
    ["name1"] = item1,
    ["name2"] = item2,
};

Обновление: если вам нужен словарь с «дублированными» строками в качестве ключа, вы можете использовать обходной путь для этой проблемы и создать словарь с пользовательским IEqualityComparer, который никогда не считает две строки одинаковыми независимо от их значений:

public class EveryStringIsUniqueueComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y) => false;
    public int GetHashCode(string obj) => Random.Shared.Next();
}

var item1 = new Dictionary<string, string>(new EveryStringIsUniqueueComparer())
{
    ["key1"] = "value1",
    ["key1"] = "value2",
    ["key1"] = "value3",
};

Спасибо за ответ! Но, боюсь, это не совсем решает. Я должен был указать, но имена могут быть не уникальными. Там может быть повтор, и, как я понимаю, это невозможно со словарем.

tbeest 23.02.2023 11:34

Я думаю, что повторение ключевых значений в json — это отдельная проблема с отдельным решением (и это серьезно усложняет десериализацию, если она вам нужна). Но вы можете использовать для этого словарь с пользовательским learn.microsoft.com/en-us/dotnet/api/… .

Vadim Martynov 23.02.2023 11:38

@tbeest вы уверены, что API позволяет дублировать ключи? Это не рекомендуется, а в некоторых местах даже запрещено

Magnetron 23.02.2023 12:39

@Magnetron спасибо за ссылку. вы правы, и это может быть неожиданное значение во многих системах и вызывать ошибки. именно поэтому я написал, что такой код вызовет проблемы при десериализации значения. Это потребует написания пользовательского десериализатора. Но при необходимости можно реализовать систему, где разрешены дубликаты ключей.

Vadim Martynov 23.02.2023 12:45

Я ошибся насчет дублирования, простите за путаницу.

tbeest 23.02.2023 14:08

Json, который вы хотите, недействителен, если имя1 может быть равно имени2. Поэтому невозможно создать json, который вы хотите. Если вы создадите его вручную, например, с помощью StringBuilder, но вы не сможете его десериализовать и получить данные (если вы не создадите свою json-библиотеку со своими правилами). Единственная структура, допускающая дублирование, — это коллекция (массив или список). Так что обсудите это с пользователями API и обновите свой пост с действительным результатом. Мы можем предложить вам десятки различных структур, которые действуют, но я не вижу в этом смысла. Вместо этого вы можете прочитать любой учебник.

ИМХО словари - не лучшие структуры для моделей данных. Всегда лучше использовать полностью типизированные объекты вместо строк. Вы должны использовать словари, только если вы не можете использовать что-либо еще.

Я повторил несколько вещей, и кажется, что вы действительно правы. С тем, как он настроен в другом месте, казалось, что могут потребоваться повторяющиеся имена, но он не обрабатывает их должным образом. Тогда это должно быть ограничение API, который мне предоставили. Простите путаницу.

tbeest 23.02.2023 14:05

Другие вопросы по теме