简体   繁体   中英

C# Deserialize JSON Response

I've written a csharp app which queries our load balancers (which are setup in an active/passive configuration) to determine which is the active. The load balancers have a REST API which I'm querying as such:

public void GetActiveLB()
{
    // Create a new RestClient and RestRequest
    var client = new RestClient("https://myloadbalancer.domain.local");
    var request = new RestRequest("mgmt/tm/cm/failover-status", Method.GET);

    // Specify authentication
    client.Authenticator = new HttpBasicAuthenticator("myusername", "supersecret");

    // ask for the response to be in JSON syntax
    request.RequestFormat = DataFormat.Json;

    //send the request to the web service and store the response when it comes back
    var queryResult = client.Execute(request);

    // Create a new Deserializer to be able to parse the JSON object
    RestSharp.Deserializers.JsonDeserializer deserial = new JsonDeserializer();
    var JSONObj = deserial.Deserialize<Dictionary<string, string>>(queryResult);
    string lbstatus = JSONObj["description"]; 
}

The JSON returned to me looks like this:

{
    "kind":"tm:cm:failover-status:failover-statusstats",
    "selfLink":"https://localhost/mgmt/tm/cm/failover-status?ver=11.6.0",
     "entries": {
         "https://localhost/mgmt/tm/cm/failover-status/0": {
          "nestedStats": {
              "entries": {
                  "color": {
                      "description": "green"
                  },
                 "https://localhost/mgmt/tm/cm/failoverStatus/0/details": {
                 "nestedStats": {
                     "entries": {
                         "https://localhost/mgmt/tm/cm/failoverStatus/0/details/0": {
                             "nestedStats": {
                                 "entries": {
                                     "details": {
                                         "description": "active for /Common/traffic-group-1"
                                     }
                                 }
                             }
                         }
                     }
                 }
             },
             "status": {
                 "description": "ACTIVE"
             },
             "summary": {
                 "description": "1/1 active"
             }
         }
     }
 }
 }}

Here's a prettier formatted version: 在此处输入图片说明 )

The path to the item I want is:

[JSON].entries.https://localhost/mgmt/tm/cm/failover-status/0.nestedStats.entries.status.description

What I am struggling with is how to get the value of this item particularly because it seems to be nested multiple times. Is there a way to provide an absolute path?

Thank You Brad

If the json is always structured the same way you can create some poco's that nest themselves and then deserialise with the json deserialisation: eg:

[DataContract]
public class JsonResponse
{ 
    [datamember]
    public string kind;
    [datamember]
    public string selflink;
    [datamember]
    public Entry entries; //we nest another object here just as in the json
}

[DataContract]
public class Entry
{ 
    [datamember]
    public nestedstat nestedstats;
}

(this is just loosly typed)

then:

JsonResponse response = new JavaScriptSerializer().Deserialize<JsonResponse>(jsonasstring);

The easiest way to do it is to use the dynamic keyword like this:

dynamic JSONObj =
    deserial
    .Deserialize<Dictionary<string, object>>(queryResult); //Notice how I am using Dictionary<string, object> instead of Dictionary<string, string> since some of the values are actually parents of other values so they will be presented as dictionaries themselves.

var lbstatus =
    JSONObj
        ["entries"]
        ["https://localhost/mgmt/tm/cm/failover-status/0"]
        ["nestedStats"]
        ["entries"]
        ["status"]
        ["description"];

If you don't use the dynamic keyword then you would have to cast JSONObj["entries"] into a Dictionary<string,object> , and then when you access ["https://localhost/mgmt/tm/cm/failover-status/0"] on that dictionary, you would need to cast the result again into Dictionary<string,object> ... etc.

In this case, the dynamic keyword will make it very much easier.

If you want to get the result from an absolute path, you can do something like this with dynamic :

dynamic JSONObj = deserial.Deserialize<Dictionary<string, object>>(queryResult);

string path =
    "entries.https://localhost/mgmt/tm/cm/failover-status/0.nestedStats.entries.status.description";

dynamic value = JSONObj;

foreach (var sub_path in path.Split('.'))
{
    value = value[sub_path];
}

var lbstatus = value.ToString();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM