-5

I'm trying to use an API to get reports but I'm having trouble getting the JSON results into usable information using JSON.NET. I've looked at quite a few examples but the correct class format for the classes is eluding me.

JSON Data:

{
    "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"
        }
    }
}

Where I'm at now:

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);

Anyone have any ideas?

Edit: Error Output:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[aEvents]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

Path 'data.event.Time', line 1, position 39.

Marty
  • 11
  • 2
  • Yesh, let's see the error. The "data" element doesn't look right. Shouldn't it be an array? Example: "data": [ "event": {...}, ... ] or maybe even Example: "data": [ {...}, {...}, ... ] – Matt Runion Sep 09 '15 at 20:00
  • 1
    Your `data` object has two properties with the same name `event` . There is no safe way to access them. Of course you can use some tricks to access the first/second one but that would be only a hack. – Eser Sep 09 '15 at 20:01
  • once you define your json correctly you can try getting the c# class with http://json2csharp.com/ – Juan Sep 09 '15 at 20:03
  • @JuanC. json is correct but not much *usable* – Eser Sep 09 '15 at 20:08
  • Your `"data"` JSON object has properties with duplicated names. For suggestions how to read such JSON, see [How to deserialize JSON with duplicate property names in the same object](http://stackoverflow.com/questions/20714160/how-to-deserialize-json-with-duplicate-property-names-in-the-same-object) or [Json.NET (Newtonsoft.Json) - Two 'properties' with same name?](http://stackoverflow.com/questions/3877526/json-net-newtonsoft-json-two-properties-with-same-name). You'll need to write a custom JsonConverter for `aData` using these two answers as a guide. – dbc Sep 09 '15 at 21:05
  • Added the error to the OP. I agree the json isn't ideal but it's being generated by a 3rd party so I don't have any control over it minus editing it manually before parsing. – Marty Sep 09 '15 at 21:08
  • I should also clarify the original json came as Event1, Event2, Event3, etc but for making classes I opted to use regex to set it all to "event" for the aData class. – Marty Sep 09 '15 at 21:15
  • 5
    Arrggggghhhhhh. Classical [XY-Problem....](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) Your problem now can be mapped to http://stackoverflow.com/questions/24536533/how-can-i-parse-a-json-string-that-would-cause-illegal-c-sharp-identifiers Simply Use Dictionary.... **a big -1** – Eser Sep 09 '15 at 21:17
  • 1
    @Marty - that decision was a mistake. Try declaring `events` as a `Dictionary` and you should be good to go with the *original* json. – dbc Sep 09 '15 at 21:18
  • @dbc thanks man. That was exactly what I needed to do. Got it working. – Marty Sep 09 '15 at 22:00

1 Answers1

-2

Try changing your data to:

{
"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"
    }
]}

And then change you class to:

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

You don't need "aData".

Dave Zych
  • 21,581
  • 7
  • 51
  • 66
andygjp
  • 2,464
  • 1
  • 16
  • 11