C# Json.Net 可以处理 List<object> 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1208030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:56:27  来源:igfitidea点击:

Can Json.Net handle a List<object>?

c#asp.netjsonjson.net

提问by mrblah

List<User> list = LoadUsers();

JObject json = new JObject();

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

Doesn't seem to be working?

似乎没有工作?

Error:

错误:

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

回答by Brian Rogers

A JValuecan only contain simple values like strings, ints, booleans, dates and the like. It cannot contain a complex object. I suspect what you really want is this:

AJValue只能包含简单的值,如字符串、整数、布尔值、日期等。它不能包含复杂的对象。我怀疑你真正想要的是这个:

List<User> list = LoadUsers();

JObject json = new JObject();

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

The above will convert the list of Userobjects into a JArrayof JObjectsrepresenting the users, then assign that to the usersproperty on the new JObject. You can confirm this by examining the Typeproperty of json["users"]and see that it is Array.

以上将User对象列表转换JArrayJObjects代表用户的 ,然后将其分配给users新的属性JObject。您可以通过检查 的Type属性json["users"]并查看它是来确认这一点 Array

In contrast, if you do json["users"] = new JValue(JsonConvert.SerializeObject(list))as was suggested in another answer to this question (now deleted), you will probably not get the result you are looking for. That approach will serialize the list of users to a string, create a simple JValuefrom that, and then assign the JValueto the usersproperty on the JObject. If you examine the Typeproperty of json["users"], you will see that it is String. What this means is, if you later try to convert the JObjectto JSON by using json.ToString(), you will get double-serialized output instead of the JSON you probably expect.

相比之下,如果您json["users"] = new JValue(JsonConvert.SerializeObject(list))按照此问题的另一个答案(现已删除)中的建议进行操作,您可能不会得到您正在寻找的结果。这一方法将序列化的用户列表为字符串,创建一个简单的JValue从,然后分配JValueusers的财产JObject。如果您检查 的Type属性json["users"],您将看到它是String。这意味着,如果您稍后尝试使用 将 转换JObject为 JSON json.ToString(),您将获得双序列化输出,而不是您可能期望的 JSON。

Here is a short demo to illustrate the difference:

这是一个简短的演示来说明差异:

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; }
    }
}

Output:

输出:

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\"}]"
}

回答by polydegmon

I had this issue, you can now use JArray to get this done, if you just want the array items with no root name.

我遇到了这个问题,如果您只想要没有根名称的数组项,您现在可以使用 JArray 来完成此操作。

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

If you want the root name of the json array to be "users", you can use

如果您希望 json 数组的根名称为“users”,则可以使用

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