JSON.NET使用JsonPropertyAttribute时的冲突属性名称

时间:2014-07-22 12:41:05

标签: c# json json.net deserialization

我有以下JSON字符串:

{
    "items" : "1",
    "itemdetails": 
    [
        {
            "id" : "5",
            "name:" "something"
        }
    ]
}

items表示项目计数,实际项目位于itemdetails

我想将其反序列化为这样的类:

class Parent
{
    JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; set; }
}

class Item
{
    [JsonProperty("id")]
    public long Id { get; set; }

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

然而,当我打电话

JsonConvert.DeserializeObject<Parent>(inputString)

我得到JsonSerializationException字符串"1"无法转换为IEnumerable<Item>。我猜解析器正在尝试将items从JSON反序列化为Items属性,因为它们按名称匹配。它忽略了JsonProperty属性。

这是设计的吗?任何解决方法?谢谢!

修改

正如Brian Rogers评论的那样,这段代码正常运行。我想我错过了添加一块拼图。

问题是我是否想使用私有集合设置器并从构造函数初始化这些属性。

public Parent(IEnumerable<Item> items)
{
    this.Items = items;
}

这导致抛出异常。我该怎么办?以某种方式注释构造函数参数?或者使用ConstructorHandling.AllowNonPublicDefaultConstructor

1 个答案:

答案 0 :(得分:0)

我看到两个问题。首先,您的JsonProperty属性格式不正确。

你有:

JsonProperty("itemdetails"]

应该是:

[JsonProperty("itemdetails")]

其次,部分JSON无效。

你有这个:

 "name:" "something",

应该是:

 "name" : "something"

解决了这两个问题后,对我来说效果很好。这是我使用的测试程序:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""items"" : ""1"",
            ""itemdetails"": 
            [
                {
                    ""id"" : ""5"",
                    ""name"" : ""something""
                }
            ]
        }";

        Parent parent = JsonConvert.DeserializeObject<Parent>(json);
        foreach (Item item in parent.Items)
        {
            Console.WriteLine(item.Name + " (" + item.Id + ")");
        }
    }
}

class Parent
{
    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; set; }
}

class Item
{
    [JsonProperty("id")]
    public long Id { get; set; }

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

输出:

something (5)

修改

好的,所以如果我理解正确的话,你的真正的 Parent类实际上是这样的:

class Parent
{
    public Parent(IEnumerable<Item> items)
    {
        this.Items = items;
    }

    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; private set; }
}

在这种情况下,你有几个选择让它起作用:

您可以在构造函数中更改参数的名称以匹配JSON,例如:

    public Parent(IEnumerable<Item> itemdetails)
    {
        this.Items = itemdetails;
    }

或者你可以为Json.Net添加一个单独的私有构造函数来使用:

class Parent
{
    public Parent(IEnumerable<Item> items)
    {
        this.Items = items;
    }

    [JsonConstructor]
    private Parent()
    {
    }

    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; private set; }
}