2

I'm writing here because I think I used all resources I could get. There must be something terribly wrong with my abstraction/approach because I cannot make it work properly. Task is quite simple - I need to iterate through nested list(??) generated from json input(or maybe I'm doing it wrong from the scratch). Using jquery with this json works great but this time I need to process data on the server side.

I got json input(example extract below):

{
   "services":[
      {
         "service_status":"CRITICAL",
         "service_host":{
            "host_status":2,
            "host_address":"192.168.1.12",
            "host_name":"test1app_srv",
            "host_problem_has_been_acknowledged":0,
            "host_has_comments":0,
            "host_notifications_enabled":1,
            "host_checks_enabled":1,
            "host_is_flapping":0,
            "host_scheduled_downtime_depth":0,
            "host_notes_url":"",
            "host_action_url":"",
            "host_icon_image":"server.gif"
         },
         "service_description":"test1app_srv",
         "service_problem_has_been_acknowledged":0,
         "service_has_comments":0,
         "service_accept_passive_service_checks":1,
         "service_notifications_enabled":1,
         "service_checks_enabled":1,
         "service_is_flapping":0,
         "service_scheduled_downtime_depth":0,
         "service_notes_url":"",
         "service_action_url":"",
         "service_icon_image":"services.gif",
         "service_state_duration":" 0d  0h  2m  7s",
         "service_last_check":"04-27-2013 23:49:55",
         "service_current_attempt":1,
         "service_max_attempts":1,
         "service_plugin_output":"CRITICAL - Throughput : Threshold '600' failed for value 720"
      },
      {}
   ]
}

from which, using http://json2csharp.com/ I've generated c# classes:

public class ServiceHost
{
    public int host_status { get; set; }
    public string host_address { get; set; }
    public string host_name { get; set; }
    public int host_problem_has_been_acknowledged { get; set; }
    public int host_has_comments { get; set; }
    public int host_notifications_enabled { get; set; }
    public int host_checks_enabled { get; set; }
    public int host_is_flapping { get; set; }
    public int host_scheduled_downtime_depth { get; set; }
    public string host_notes_url { get; set; }
    public string host_action_url { get; set; }
    public string host_icon_image { get; set; }
}

public class Service
{
    public string service_status { get; set; }
    public ServiceHost service_host { get; set; }
    public string service_description { get; set; }
    public int service_problem_has_been_acknowledged { get; set; }
    public int service_has_comments { get; set; }
    public int service_accept_passive_service_checks { get; set; }
    public int service_notifications_enabled { get; set; }
    public int service_checks_enabled { get; set; }
    public int service_is_flapping { get; set; }
    public int service_scheduled_downtime_depth { get; set; }
    public string service_notes_url { get; set; }
    public string service_action_url { get; set; }
    public string service_icon_image { get; set; }
    public string service_state_duration { get; set; }
    public string service_last_check { get; set; }
    public int service_current_attempt { get; set; }
    public int service_max_attempts { get; set; }
    public string service_plugin_output { get; set; }
}

public class NagiosRootObject
{
    public List<Service> services { get; set; }
}

I managed to get the NagiosRootObject.services content but I cannot access values from Service.service_host. I focused on an approach utilizing

NagiosRootObject obj = JsonConvert.DeserializeObject<NagiosRootObject>(json);

I have all above and I'm using Json.NET from http://json.codeplex.com.

I have tried hints from

and few related but witho no luck.

Knowing that there is so many tutorials and not being able to make use of it makes me really sad.. Help would be appreciated. This post is the last resort for this task... I need serious tips. Thank You

Community
  • 1
  • 1
abacki.john
  • 43
  • 10
  • 1
    `but I cannot access values from Service.service_host`? What do you mean? your code works correctly.... – I4V Apr 29 '13 at 07:50
  • Yes, code compiles perfectly but the problem is I can access only top level of json data. If You look at json input, for every section there is "service_host" element. Is there any easy way to eg. do Response.Write all values from a "service"? Right now I need to access service_status, status_description and service_host.host_address and service_host.host_name. I managed to get just the first two values with no luck in getting the other. Do You know how this can be achieved? – abacki.john Apr 30 '13 at 07:17
  • As I said, *your code works correctly*. Debug your code and look into `obj`. It contains all the data you are after. – I4V Apr 30 '13 at 07:25
  • If I get an object list I can run foreach on int eg. `NagiosRootObject obj = JsonConvert.DeserializeObject(json); foreach (var item in obj.services) { Response.Write(item.service_status + "
    "); Response.Write(item.service_host.host_name + "
    "); // <-- it fails for such entries }` Sth like that will compile but it will throw en exception when accessing item.service_host.host_name. I get System.NullReferenceException: Object reference not set to an instance of an object. What am I doing wrong? I feel like my thinking goes backwards.
    – abacki.john Apr 30 '13 at 08:52
  • 1
    Look at your json, You have 2 elements in your list but the second one is `{}`(*all properties are null*). Just include null checks in your code. – I4V Apr 30 '13 at 08:54

3 Answers3

0

Using json.NET the following code works: (after putting your json in a file called 'json.txt')

using (var reader = File.OpenText("json.txt"))
{
    var ser = JsonSerializer.Create(null);
    var jReader = new JsonTextReader(reader);
    var grp = ser.Deserialize<NagiosRootObject>(jReader);

}

However, the list is populated by two objects, and in the 2nd one all the values are null. This is because you have an empty element {} in your json.

Edit: Your code works just as well in my test, so no need to change it.

havardhu
  • 3,576
  • 2
  • 30
  • 42
  • The problem with deserialization in my case is mainly the problem with accessing nested elements from json object. It seems that all code I pasted above works and now I'm looking for a code solution for this matter. ..and yes, there is an empty element at the end of the json string. The input is generated automatically on the remote host, so it is beyond my control. – abacki.john Apr 30 '13 at 07:28
0

Have you tried:

var obj = new JavaScriptSerializer().Deserialize<NagiosRootObject>(jsonString);
mridula
  • 3,203
  • 3
  • 32
  • 55
-5

If you want to parse this json in server then it is better to parse this json into XML and utilize that xml to traverse. In server side coding xml traversing is easy. Especially in C#.

Convert the json into XMl or wise versa using newtonsoft dll. The code to parse json to XMl is

 XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);

Dpwnload the dll from the link http://json.codeplex.com/

I hope this will help you.

  • Because server side languages like C# have build in classes and methods to handle XML. In the case of json the client side scripting languages helps more than server side languages. – Kirubhananth Chellam Apr 29 '13 at 08:09
  • 3
    *server side languages like C# have build in classes and methods to handle Json too* :) – I4V Apr 29 '13 at 08:10
  • 1
    Couldn't disagree more. Why would you want to convert from one transport format to another? There are excellent json parsers available which deserializes json into POCOs. POCOs are much easier to work with and ensures far better code readability – havardhu Apr 29 '13 at 08:16
  • 1
    Sorry, but I'm trying to avoid mixing standards. The reason I stick with json is high integration with the software I'm already working with and it is easy enough for the top management to handle when it comes to report the progress of work ;) – abacki.john Apr 30 '13 at 07:33