Для интеграции с 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» и т. д. Обновлено: я ошибся, игнорируйте следующую часть. Имена могут повторяться, комбинация имени и второй переменной должна быть уникальной. Я мог бы вручную создать правильную строку с заданными переменными, но я чувствую, что должен быть лучший, "правильный" способ добиться этого.
Редактировать: рабочий пример
Добро пожаловать в StackOverflow! Не могли бы вы поделиться с нами определением исходного объекта с некоторыми примерами данных? Мы могли бы помочь вам лучше, если бы вы поделились с нами минимально воспроизводимым примером
Вы можете использовать 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",
};
Спасибо за ответ! Но, боюсь, это не совсем решает. Я должен был указать, но имена могут быть не уникальными. Там может быть повтор, и, как я понимаю, это невозможно со словарем.
Я думаю, что повторение ключевых значений в json — это отдельная проблема с отдельным решением (и это серьезно усложняет десериализацию, если она вам нужна). Но вы можете использовать для этого словарь с пользовательским learn.microsoft.com/en-us/dotnet/api/… .
@tbeest вы уверены, что API позволяет дублировать ключи? Это не рекомендуется, а в некоторых местах даже запрещено
@Magnetron спасибо за ссылку. вы правы, и это может быть неожиданное значение во многих системах и вызывать ошибки. именно поэтому я написал, что такой код вызовет проблемы при десериализации значения. Это потребует написания пользовательского десериализатора. Но при необходимости можно реализовать систему, где разрешены дубликаты ключей.
Я ошибся насчет дублирования, простите за путаницу.
Json, который вы хотите, недействителен, если имя1 может быть равно имени2. Поэтому невозможно создать json, который вы хотите. Если вы создадите его вручную, например, с помощью StringBuilder, но вы не сможете его десериализовать и получить данные (если вы не создадите свою json-библиотеку со своими правилами). Единственная структура, допускающая дублирование, — это коллекция (массив или список). Так что обсудите это с пользователями API и обновите свой пост с действительным результатом. Мы можем предложить вам десятки различных структур, которые действуют, но я не вижу в этом смысла. Вместо этого вы можете прочитать любой учебник.
ИМХО словари - не лучшие структуры для моделей данных. Всегда лучше использовать полностью типизированные объекты вместо строк. Вы должны использовать словари, только если вы не можете использовать что-либо еще.
Я повторил несколько вещей, и кажется, что вы действительно правы. С тем, как он настроен в другом месте, казалось, что могут потребоваться повторяющиеся имена, но он не обрабатывает их должным образом. Тогда это должно быть ограничение API, который мне предоставили. Простите путаницу.
Вам нужно использовать словарь строкового поля вместо списка