【问题标题】:How to Convert a Set of JSON Objects to C# List如何将一组 JSON 对象转换为 C# 列表
【发布时间】:2018-06-29 22:38:43
【问题描述】:

我有一个如下所示的 JSON 文件:

{
    "foo": "bar",
    "pets": {
        "dog": {
            "name": "spot",
            "age": "3"
        },
        "cat": {
            "name": "wendy",
            "age": "2"
        }
    }
}

我想将其反序列化为 C# 类:

public class PetObject
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("age")]
    public string Age { get; set; }
}

public class FooObject
{
    [JsonProperty("foo")]
    public string Foo { get; set; }

    [JsonProperty("pets")]
    public List<PetObject> Pets { get; set; }
}

使用类似这样的代码进行转换是行不通的,因为 pets 里面有多个对象,而且不是 JSON 数组。

//does not work
FooObject content = JsonConvert.DeserializeObject<FooObject>(json);

这里是例外:

Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Test.PetObject]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'pets.dog', line 4, position 10.

有没有办法将 pets 对象中的对象转换为对象数组? (除了在传递给 DeserializeObject 方法之前编辑 JSON 本身)

【问题讨论】:

  • 您必须考虑"dog""cat" 应该在您的数据结构中。我在您的 json 中看不到任何适合这些标签的属性。除此之外,“它不起作用”并不是一个好的问题描述。相反,请包括您得到的确切错误(如果有),或结果连同您的预期。
  • 您的pets 属性根本不是List,更像是Dictionary&lt;string, PetObject&gt;。此外,该属性称为 petsnot PetObjects,就像在您的班级中一样。
  • @HimBromBeere 抱歉,对这个平台还是有点陌生​​,我稍微澄清了帖子并添加了实际错误。

标签: c# json json.net json-deserialization


【解决方案1】:

您的 JSON 文件包含宠物字典,而不是数组。所以,更改FooObject 类:

public class FooObject
{
    [JsonProperty("foo")]
    public string Foo { get; set; }

    [JsonProperty("pets")]
    public Dictionary<string, PetObject> Pets { get; set; }

    // if you still need a list of pets, use this
    public List<PetObject> PetsList => Pets.Values.ToList();
}

【讨论】:

  • 没有人看到这里的问题是类名和属性名冲突?
  • 我只是从问题中复制了它。没关系……但只为你,我修好了。
【解决方案2】:

这是一个糟糕的 json。但是,您可以使用JsonProperty 属性对其进行反序列化,如下所示:

class Program
{
    static void Main(string[] args)
    {
        string json = "{\"foo\": \"bar\",\"pets\": {\"dog\": {\"name\": \"spot\",\"age\": \"3\"},\"cat\": {\"name\": \"wendy\",\"age\": \"2\"}}}";
        Foo content = JsonConvert.DeserializeObject<Foo>(json);

        Console.Read();
    }
}

public class PetObject
{
   [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("age")]
    public string Age { get; set; }
}

public class Foo
{
    [JsonProperty("foo")]
    public string FooStr { get; set; }

    [JsonProperty("pets")]
    public Dictionary<string, PetObject> Pets { get; set; }
}

【讨论】:

  • 为什么是“构造错误的 json”?
  • @EdSF 当然,我试过了,效果很好。我对 json 的问题是它包含以小写字符开头的键,我不想鼓励任何人在他们的模型中使用这些属性。
  • 您的模型属性名称(实际上)并不重要 - 正如您的代码所示(使用 JsonProperty 属性)。另外,您可以使用CamelCasePropertyNamesContractResolver
【解决方案3】:

您的json 确实“对象数组”。它说它有一个带有dogcat 属性的pets 对象。所以是这样的:

public class PetObject
{
    public string name { get; set; }
    public string age { get; set; }
}

public class Foo
{
    public string foo { get; set; }
    public Pets pets {get;set;}

}

public class Pets
{
    public PetObject dog { get; set; }
    public PetObject cat { get; set;}
}

public class Program
{
    public static void Main()
    {
        var json = "{\"foo\": \"bar\",\"pets\": {\"dog\": {\"name\": \"spot\",\"age\": \"3\"},\"cat\": {\"name\": \"wendy\",\"age\": \"2\"}}}"; 

        var content = JsonConvert.DeserializeObject<Foo>(json);

        Console.WriteLine(content.pets.dog.name);   

    }
}

第...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多