Подтвердить что ты не робот

Может ли Json.Net обрабатывать List <object>?

List<User> list = LoadUsers();

JObject json = new JObject();

json["users"] = new JValue(list);

Кажется, что не работает?

Ошибка:

Could not determine JSON object type for type System.Collections.Generic.List`1
4b9b3361

Ответ 1

A JValue может содержать только простые значения, такие как строки, ints, boolean, даты и т.п. Он не может содержать сложный объект. Я подозреваю, что вы действительно этого хотите:

List<User> list = LoadUsers();

JObject json = new JObject();

json["users"] = JToken.FromObject(list);

Вышеописанное преобразует список объектов User в JArray of JObjects, представляющий пользователей, а затем присваивает это свойство users в новом JObject. Вы можете подтвердить это, изучив свойство Type json["users"] и увидите, что это Array.

В отличие от этого, если вы делаете json["users"] = new JValue(JsonConvert.SerializeObject(list)), как было предложено в другом ответе на этот вопрос (теперь он удален), вы, вероятно, не получите результат, который вы ищете. Этот подход будет сериализовать список пользователей в строке, создать из него простой JValue, а затем присвоить JValue свойству users на JObject. Если вы изучите свойство Type json["users"], вы увидите, что оно String. Это означает, что если позже вы попытаетесь преобразовать JObject в JSON с помощью json.ToString(), вы получите двойной сериализованный вывод вместо ожидаемого JSON.

Вот краткий демонстрационный пример, иллюстрирующий разницу:

class Program
{
    static void Main(string[] args)
    {
        List<User> list = new List<User>
        {
            new User { Id = 1, Username = "john.smith" },
            new User { Id = 5, Username = "steve.martin" }
        };

        JObject json = new JObject();

        json["users"] = JToken.FromObject(list);
        Console.WriteLine("First approach (" + json["users"].Type + "):");
        Console.WriteLine();
        Console.WriteLine(json.ToString(Formatting.Indented));

        Console.WriteLine();
        Console.WriteLine(new string('-', 30));
        Console.WriteLine();

        json["users"] = new JValue(JsonConvert.SerializeObject(list));
        Console.WriteLine("Second approach (" + json["users"].Type + "):");
        Console.WriteLine();
        Console.WriteLine(json.ToString(Formatting.Indented));
    }

    class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
    }
}

Вывод:

First approach (Array):

{
  "users": [
    {
      "Id": 1,
      "Username": "john.smith"
    },
    {
      "Id": 5,
      "Username": "steve.martin"
    }
  ]
}

------------------------------

Second approach (String):

{
  "users": "[{\"Id\":1,\"Username\":\"john.smith\"},{\"Id\":5,\"Username\":\"steve.martin\"}]"
}

Ответ 2

У меня была эта проблема, теперь вы можете использовать JArray, чтобы это сделать, если вам просто нужны элементы массива без имени root.

var json = JArray.FromObject(LoadUsers());

Если вы хотите, чтобы корневое имя json-массива было "пользователем", вы можете использовать

var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) };