Может ли Json.Net обрабатывать список <object>? - PullRequest
22 голосов
/ 30 июля 2009
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

Ответы [ 2 ]

51 голосов
/ 25 декабря 2013

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

List<User> list = LoadUsers();

JObject json = new JObject();

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

Приведенный выше код преобразует список User объектов в JArray из 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\"}]"
}
3 голосов
/ 04 января 2018

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

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

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

var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...