У меня есть следующая строка 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
.
Это по дизайну? Любые обходные пути? Благодарю!
РЕДАКТИРОВАТЬ
Как заметил Брайан Роджерс, этот код работает правильно. Я подумал, что я пропустил, чтобы добавить кусочек головоломки.
Проблема в том, что я хочу использовать частные сборщики и инициализировать эти свойства из конструктора.
public Parent(IEnumerable<Item> items)
{
this.Items = items;
}
Это вызывает исключение исключения. Что мне здесь делать? Аннотировать аргументы конструктора каким-то образом? Или используйте ConstructorHandling.AllowNonPublicDefaultConstructor
?
Я вижу два вопроса. Во-первых, ваш JsonProperty
атрибут 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; }
}
JsonProperty
в JsonProperty
«Items».