Десериализация массива объектов JSON с классами Json.net

Я пытаюсь использовать API для получения отчетов, но у меня возникают проблемы с преобразованием результатов JSON в полезную информацию с использованием JSON.NET. Я просмотрел довольно много примеров, но правильный формат класса для классов ускользает от меня.

Данные JSON:

{
    "status": "OK",
    "data": {
        "event": {
            "Time": "2015-09-01 17:31:47",
            "Username": "user1",
            "IP_Address": "1.2.3.4",
            "Action": "action1",
            "Data": "somedata"
        },
        "event": {
            "Time": "2015-09-01 17:30:30",
            "Username": "user2",
            "IP_Address": "1.2.3.5",
            "Action": "action2",
            "Data": "data"
        }
    }
}

Где я сейчас:

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

public class aRoot
{
  [JsonProperty("status")]
  public string status { get; set; }
  [JsonProperty("data")]
  public aData data { get; set; }
}

public class aData
{
  [JsonProperty("event")]
  public List<aEvents> events { get; set; }
}

public class aEvents
{
  [JsonProperty("Time")]
  public DateTime time { get; set; }
  [JsonProperty("UserName")]
  public string user { get; set; }
  [JsonProperty("IP_Address")]
  public string ip { get; set; }
  [JsonProperty("Action")]
  public string action { get; set; }
  [JsonProperty("Data")]
  public string data { get; set; }
}
aRoot objReporting = JsonConvert.DeserializeObject<aRoot>(result);

У кого-нибудь есть идеи?

Изменить: вывод ошибки:

Исключение типа «Newtonsoft.Json.JsonSerializationException» возникло в Newtonsoft.Json.dll, но не было обработано в пользовательском коде.

Дополнительная информация: Невозможно десериализовать текущий объект JSON (например, {"name":"value"}) в тип "System.Collections.Generic.List`1[aEvents]", поскольку для этого типа требуется массив JSON (например, [1,2 ,3]) для правильной десериализации.

Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3]), либо измените десериализованный тип, чтобы он был обычным типом .NET (например, не примитивный тип, такой как целое число, а не тип коллекции, такой как массив или список), который можно десериализовать из объекта JSON. JsonObjectAttribute также можно добавить к типу, чтобы заставить его десериализоваться из объекта JSON.

Путь 'data.event.Time', строка 1, позиция 39.


person Marty    schedule 09.09.2015    source источник
comment
Еш, давайте посмотрим на ошибку. Элемент данных выглядит неправильно. Разве это не должен быть массив? Пример: данные: [ событие: {...}, ... ] или, может быть, даже Пример: данные: [ {...}, {...}, ... ]   -  person mrunion    schedule 09.09.2015
comment
Ваш объект data имеет два свойства с одинаковыми именами event . Нет безопасного способа получить к ним доступ. Конечно, вы можете использовать некоторые приемы для доступа к первому/второму, но это будет только взлом.   -  person Eser    schedule 09.09.2015
comment
как только вы правильно определите свой json, вы можете попробовать получить класс c# с помощью json2csharp.com   -  person Juan    schedule 09.09.2015
comment
@ХуанС. json правильный, но не очень полезный   -  person Eser    schedule 09.09.2015
comment
Ваш объект "data" JSON имеет свойства с повторяющимися именами. Рекомендации по чтению такого JSON см. в разделе Как десериализовать JSON с повторяющимися именами свойств в одном объекте или Json.NET (Newtonsoft.Json) — Два «свойства» с одинаковыми именами?. Вам нужно будет написать собственный JsonConverter для aData, используя эти два ответа в качестве руководства.   -  person dbc    schedule 10.09.2015
comment
Добавил ошибку в ОП. Я согласен, что json не идеален, но он создается третьей стороной, поэтому у меня нет никакого контроля над ним, за исключением редактирования вручную перед разбором.   -  person Marty    schedule 10.09.2015
comment
Я также должен уточнить, что исходный json пришел как Event1, Event2, Event3 и т. д., но для создания классов я решил использовать регулярное выражение, чтобы установить все это в событие для класса aData.   -  person Marty    schedule 10.09.2015
comment
Аррггггххххх. Классическая XY-Problem.... Ваша проблема теперь может быть сопоставлена ​​с stackoverflow.com/questions/24536533/ Просто используйте словарь.... большой -1   -  person Eser    schedule 10.09.2015
comment
@Марти - это решение было ошибкой. Попробуйте объявить events как Dictionary<string, aEvents>, и вы должны хорошо работать с оригинальным json.   -  person dbc    schedule 10.09.2015
comment
@dbc спасибо, чувак. Это было именно то, что мне нужно было сделать. Все заработало.   -  person Marty    schedule 10.09.2015


Ответы (1)


Попробуйте изменить свои данные на:

{
"status": "OK",
"data": [
    {
        "Time": "2015-09-01 17:31:47",
        "Username": "user1",
        "IP_Address": "1.2.3.4",
        "Action": "action1",
        "Data": "somedata"
    },
    {
        "Time": "2015-09-01 17:30:30",
        "Username": "user2",
        "IP_Address": "1.2.3.5",
        "Action": "action2",
        "Data": "data"
    }
]}

А затем измените свой класс на:

public class aRoot
{
  [JsonProperty("status")]
  public string status { get; set; }
  [JsonProperty("data")]
  public List<aEvents> data { get; set; }
}

Вам не нужно "aData".

person andygjp    schedule 09.09.2015
comment
Я думаю, что I'm trying to use an API противоречит Try changing your data to - person Eser; 09.09.2015