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

5
  • 1
    but I cannot access values from Service.service_host? What do you mean? your code works correctly.... Commented Apr 29, 2013 at 7: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? Commented Apr 30, 2013 at 7:17
  • As I said, your code works correctly. Debug your code and look into obj. It contains all the data you are after. Commented Apr 30, 2013 at 7:25
  • If I get an object list I can run foreach on int eg. NagiosRootObject obj = JsonConvert.DeserializeObject<NagiosRootObject>(json); foreach (var item in obj.services) { Response.Write(item.service_status + "<br>"); Response.Write(item.service_host.host_name + "<hr>"); // <-- 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. Commented Apr 30, 2013 at 8: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. Commented Apr 30, 2013 at 8:54

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
0

Have you tried:

var obj = new JavaScriptSerializer().Deserialize<NagiosRootObject>(jsonString);

Comments

-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.

4 Comments

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.
server side languages like C# have build in classes and methods to handle Json too :)
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
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 ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.