Я пытаюсь загрузить данные JSON в свою базу данных. Данные хорошо структурированы и могут повторяться по всей структуре. Для повторяющихся элементов я хотел бы использовать идентификаторы и ссылки, поэтому мне не нужно дублировать код.
В настоящее время я использую json.NET для десериализации и не могу получить ссылки для правильной десериализации. Я постоянно получаю нулевые значения для элементов, которые пытаюсь заполнить ссылками.
Я попытался структурировать ссылки множеством способов, используя как идентификаторы, так и синтаксис URI. Я получил тот же результат, независимо от того, как я структурирую ссылки.
Вот код C #, который я использую для десериализации:
String dir = Directory.GetCurrentDirectory() + "\\wwwroot\\json\\";
String incidentJson = System.IO.File.ReadAllText(dir + "incident_test.json");
IncidentArray incidents = JsonConvert.DeserializeObject<IncidentArray>(
incidentJson
,new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }
);
Вот класс, к которому я пытаюсь десериализовать данные:
public class IncidentArray
{
public Incident[] Incidents { get; set; }
}
public class Incident
{
public Jurisdiction Jurisdiction { get; set; }
}
public class Jurisdiction
{
public String Code { get; set; }
public String Name { get; set; }
public String Description { get; set; }
}
Вот инцидент_test.json, который отлично разбирается:
{
"incidents": [
{
"jurisdiction": {
"code": "CD",
"name": "City Division",
"description": "City Division, Portland OR USA"
}
}
]
}
А вот инцидент_test.json со ссылками. В десериализованном объекте юрисдикция не указана:
{
"incidents": [
{
"jurisdiction": { "$ref": "1" }
}
],
"definitions": {
"jurisdiction": {
"$id": "1",
"code": "CD",
"name": "City Division",
"description": "City Division, Portland OR USA"
}
}
}
Я ожидаю, что объект, полученный в результате десериализации, будет заполнен данными в ссылочных данных json. Как уже говорилось, вместо этого я получаю нулевое значение.
РАЗРЕШЕНО : desmondgc определенно указал мне правильное направление своим ответом ниже, но это немного больше, чем порядок объектов. Я провел еще несколько тестов с учетом порядка и размещения объектов. Это десериализует и захватывает ссылку:
{
"incidents": [
{
"jurisdiction": {
"$id": "1",
"code": "CD",
"name": "City Division",
"description": "City Division, Portland OR USA"
}
},
{
"jurisdiction": { "$ref": "1" }
}
]
}
и если я создам десериализатор следующим образом:
IncidentArray incidents = JsonConvert.DeserializeObject<IncidentArray(
incidentJson
,new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.All
,MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
}
);
Это тоже работает:
{
"incidents": [
{
"jurisdiction": {
"code": "CD",
"name": "City Division",
"$id": "1",
"description": "City Division, Portland OR USA"
}
},
{
"jurisdiction": { "$ref": "1" }
}
]
}
из-за свойства MetadataPropertyHandling.
Очевидно, здесь важен порядок, и в моих исходных данных испытаний порядок был неправильным. Однако другим важным фактором, по-видимому, является тот факт, что в моем первоначальном тесте json объект с идентификатором ссылки фактически не десериализовался, потому что он не соответствовал структуре объекта, к которому я десериализовался. В результате не было объекта, который можно было бы скопировать в эталонный объект, когда десериализатор пытался его обработать.
Так важен порядок, но важна и структура объекта. Свойство id должно помечать объект, который будет обрабатывать десериализатор, а эталонный объект должен находиться в том месте на графе объектов, где десериализатор распознает его как тот же тип, что и исходный объект.