无法反序列化Json数据

piv4azn7  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(105)

我有一个JSON数据,我想反序列化和加载。
我能够反序列化和加载部分数据,但不是全部。下面是代码和JSON数据。

public class Category
{
public string CategoryID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ParentCategoryID { get; set; }
public string CountDiscussions { get; set; }
public string CountComments { get; set; }
public JObject Children { get; set; }
}

public class ChildCategory
{
public int CategoryID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int ParentCategoryID { get; set; }
public int CountDiscussions { get; set; }
public int CountComments { get; set; }
public JArray Children { get; set; }
}

public class Program
{
public static void Main()
{
    string jsonData = @"[
        {   
    ""categoryID"": 93,
    ""name"": ""Cloths"",
    ""description"": """",
    ""parentCategoryID"": null,
    ""countDiscussions"": 10,
    ""countComments"": 20,
    ""children"": {
        ""57"": {
            ""categoryID"": 180,
            ""name"": ""Shirt"",
            ""description"": """",
            ""parentCategoryID"": 9,
            ""countDiscussions"": 2,
            ""countComments"": 4,
            ""children"": []
        },
        ""56"": {
            ""categoryID"": 187,
            ""name"": ""ShirtAAAAA"",
            ""description"": """",
            ""parentCategoryID"": 9,
            ""countDiscussions"": 2,
            ""countComments"": 4,
            ""children"": []
        }
    }
},
{
    ""categoryID"": 172,
    ""name"": ""accessories"",
    ""description"": """",
    ""parentCategoryID"": null,
    ""countDiscussions"": 15,
    ""countComments"": 47,
    ""children"": {
        ""2"": {
            ""categoryID"": 191,
            ""name"": ""Watch"",
            ""description"": """",
            ""parentCategoryID"": 172,
            ""countDiscussions"": 1,
            ""countComments"": 0,
            ""children"": []
        }
    }
},
**{**
    **""categoryID"": 117,**
    **""name"": ""jewellery"",**
    **""description"": """",**
    **""parentCategoryID"": null,**
    **""countDiscussions"": 243,**
    **""countComments"": 6716,**
    **""children"": []**
**}**
    ]";

    var categories = JsonConvert.DeserializeObject<Category[]>(jsonData);

    foreach (var category in categories)
    {
        Console.WriteLine($"Category ID: {category.CategoryID}");
        Console.WriteLine($"Name: {category.Name}");
        Console.WriteLine($"Description: {category.Description}");
        Console.WriteLine($"Parent Category ID: {category.ParentCategoryID}");
        Console.WriteLine($"Count of Discussions: {category.CountDiscussions}");
        Console.WriteLine($"Count of Comments: {category.CountComments}");
        Console.WriteLine("Children:");
        foreach (var childCategory in category.Children)
        
        {
            var child = childCategory.Value.ToObject<ChildCategory>();
            Console.WriteLine($"    Category ID: {child.CategoryID}");
            Console.WriteLine($"    Name: {child.Name}");
            Console.WriteLine($"    Description: {child.Description}");
            Console.WriteLine($"    Parent Category ID: {child.ParentCategoryID}");
            Console.WriteLine($"    Count of Discussions: {child.CountDiscussions}");
            Console.WriteLine($"    Count of Comments: {child.CountComments}");
        }
    }
}
}

字符串
如果不包括最后一个节点(categoryID=117,用**突出显示),我就能够加载数据。但是如果我包含它,那么我的代码就失败了。有谁能帮我解决这个问题吗?

fdx2calv

fdx2calv1#

我想一节课应该够了

var categories = JsonConvert.DeserializeObject<Category[]>(jsonData);

public class Category
{
    public string CategoryID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string ParentCategoryID { get; set; }
    public string CountDiscussions { get; set; }
    public string CountComments { get; set; }
    public Dictionary<int, Category> Children { get; set; }
    public Category[] ChildrenArray { get; set; }

    public Category(JToken Children)
    {
        if(Children.Type == JTokenType.Object) this.Children=Children.ToObject<Dictionary<int, Category>>();
        else ChildrenArray = Children.ToObject<Category[]>();
    }
}

字符串
或者,如果您更喜欢JObject和JArray,请将其更改为JToken

public class Category
{
//...another properties

public JToken Children { get; set; }
}


但恕我直言,最好是通过将字典转换为数组来统一子属性

public class Category
{
    //...another properties

    public int? Id { get; set; }
    public List<Category> Children { get; set; }

    [JsonConstructor]
    public Category(JToken Children)
    {
        if (Children.Type == JTokenType.Object)
        {
            this.Children=new List<Category>();
            foreach (var prop in ((JObject)Children).Properties())
            {
                prop.Value["Id"] = prop.Name;
                this.Children.Add(prop.Value.ToObject<Category>());
            }
        }
        else this.Children = Children.ToObject<List<Category>>();
    }
}


或者你也可以把这段代码 Package 在一个JSON转换器中,而不是JSON构造函数中

public class Category
{
    //...another properties
    
    public int? Id { get; set; }
    
    [JsonConverter(typeof(ChildrenConverter))]
    public List<Category> Children { get; set; }
}

public class ChildrenConverter : JsonConverter<List<Category>>
{
    public override List<Category> ReadJson(JsonReader reader, Type objectType, List<Category> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var childrenObj = JToken.Load(reader);

        if (childrenObj.Type == JTokenType.Object)
        {
            var children = new List<Category>();
            foreach (var prop in ((JObject)childrenObj).Properties())
            {
                prop.Value["Id"] = prop.Name;
                children.Add(prop.Value.ToObject<Category>());
            }
            return children;
        }
        return childrenObj.ToObject<List<Category>>();
    }

    public override void WriteJson(JsonWriter writer, List<Category> value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

yiytaume

yiytaume2#

虽然使用一个类别类会更好(如前一篇文章所述),但如果您希望保持结构大致相同:
问题1:Category类需要读取对象的字典:

public JObject Children { get; set; }

字符串
这应该是:

public Dictionary<string, JObject> Children { get; set; }


问题2:导致错误的Json部分的Children条目应该是对象类型而不是数组。您可以将其更改为使用{}而不是[]作为空的子条目:

{
    ""categoryID"": 117,
    ""name"": ""jewellery"",
    ""description"": """",
    ""parentCategoryID"": null,
    ""countDiscussions"": 243,
    ""countComments"": 6716,
    ""children"": {}
}


问题3:虽然它仍然会运行,但为了更正确,您应该使用正确的数据类型来阅读JSON。Category类的以下属性:

public string ParentCategoryID { get; set; }
public string CountDiscussions { get; set; }
public string CountComments { get; set; }


这些都应该是整数,并且ParentCategoryID需要是可空的,以便允许它在Json中为空的情况:

public int? ParentCategoryID { get; set; }
public int CountDiscussions { get; set; }
public int CountComments { get; set; }


在ChildCategory类中,我们有同样的问题,但我们不需要ParentCategoryID为空,因为这不可能发生。所以它们应该是:

public int ParentCategoryID { get; set; }
public int CountDiscussions { get; set; }
public int CountComments { get; set; }

相关问题