我有以下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
?
答案 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; }
}