我有一个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
?
我看到两个问题。首先,您的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)
编辑
如果我没理解错的话,你的真正的父类实际上是这样的: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; }
}