C#反序列化JSON响应

时间:2016-01-03 20:43:27

标签: c# json rest deserialization

我编写了一个csharp应用程序,用于查询我们的负载均衡器(在主动/被动配置中设置)以确定哪个是活动的。负载均衡器有一个REST API,我正在查询:

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

返回给我的JSON看起来像这样:

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

这是一个更漂亮的格式化版本:enter image description here

我想要的项目的路径是:

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

我正在努力的是如何获得此项目的价值,特别是因为它似乎嵌套了多次。有没有办法提供绝对路径?

谢谢 布拉德

2 个答案:

答案 0 :(得分:1)

如果json的结构总是以相同的方式创建一些自己嵌套的poco,然后使用json反序列化进行反序列化: 例如:

[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;
}

(这只是松散的类型)

然后:

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

答案 1 :(得分:0)

最简单的方法是使用dynamic关键字,如下所示:

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"];

如果您不使用dynamic关键字,则必须将JSONObj["entries"]投射到Dictionary<string,object>,然后当您在该字典上访问["https://localhost/mgmt/tm/cm/failover-status/0"]时,需要将结果再次转换为Dictionary<string,object> ......等等。

在这种情况下,dynamic关键字会让您更加轻松。

如果您想从绝对路径获取结果,可以使用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();