【问题标题】:How to structure a class so that it can be used to deserialize a JSON string that has nested elements如何构造一个类,使其可用于反序列化具有嵌套元素的 JSON 字符串
【发布时间】:2017-01-10 20:13:53
【问题描述】:

我正在使用一个返回 JSON 响应的 API,如下所示;

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: length

{
  "SAPISetPermitInfo_response" : {
    "RC" : "value",
    "MessageText" : "value"
  }
}

我想创建一个可以与

一起使用的 c# 类定义
JsonConvert.DeserializeObject<SAPISetPermitInfoResponse>(response); 

但由于嵌套元素,我不确定如何构造 SAPISetPermitInfoResponse 类,以便它与响应 JSON 字符串一起正常工作。

目前,我们正在使用辅助方法从 JSON 字符串中去除“SAPISetPermitInfo_response”元素,然后反序列化结果,如下所示...

IDictionary<string, JToken> foo = JObject.Parse(response);
string key = foo.Keys.FirstOrDefault(k => k.EndsWith("_response"));
response = JsonConvert.SerializeObject(foo[key]); 

但是,似乎应该有一种方法可以创建 SAPISetPermitInfoResponse 类,以便它允许嵌套元素而不需要帮助方法来解析 JSON 字符串。但是,到目前为止,我还没有找到任何运气。

我看过一篇帖子,他们建议创建两个类,一个只有一个字典属性 type ,其中对象是另一个具有 RC 和 MessageText 属性的类,但这似乎有点麻烦,应该需要两个类对于每个不同的 API 方法响应。 (这个 API 有大约 90 种不同的方法,它们都返回一个 JSON 响应,该响应以方法名称开头,后跟“_response”,以类似的嵌套方式)。

我无法控制 API 的响应字符串,所以我必须使用我得到的内容。我只是想确保我以正确和最有效的方式进行操作。

提前感谢您的帮助。

【问题讨论】:

    标签: c# json json.net deserialization


    【解决方案1】:

    试试这个:

    public class Result
    {
        public SAPISetPermitInfo SAPISetPermitInfo_response { get; set; }
    }
    
    public class SAPISetPermitInfo
    {
        public string RC { get; set; }
    
        public string MessageText { get; set; }
    }
    

    然后:

    string json = ... the JSON shown in your question
    var response = JsonConvert.DeserializeObject<Result>(json);
    Console.WriteLine(response.SAPISetPermitInfo_response.RC);
    Console.WriteLine(response.SAPISetPermitInfo_response.MessageText);
    

    【讨论】:

      【解决方案2】:

      您需要做的是创建以下类:

      public class SAPISetPermitInfoResponse
      {
          public string RC { get; set; }
          public string MessageText { get; set; }
      }
      
      public class RootObject
      {
          public SAPISetPermitInfoResponse SAPISetPermitInfo_response { get; set; }
      }
      

      当您想要解析所需的 Json 时,您需要能够仅从 API 响应中获取没有标头的 Json,假设我们有

      string responseJson = "{ \"SAPISetPermitInfo_response\" : {\"RC\" : \"value\",\"MessageText\" : \"value\"}}";
      

      我们可以把它发送到下面的函数中,从Json字符串中获取对象:

          public RootObject GetObjectFromResponse(string responseJson)
          {
              return JsonConvert.DeserializeObject<RootObject>(responseJson);
          }
      

      也只是为了知识,您可以使用以下站点创建任何给定的 Json 到类对象:

      http://json2csharp.com/

      【讨论】:

      • 鉴于 API 有大约 90 个方法,并且每个方法都返回一个方法名称后跟“_response”的结果,这个解决方案是否意味着我需要为每种方法(一个用于方法属性,一个用于每个不同的方法根。或者,如果我的 RootObject 类具有每种不同方法的属性(因此 1 个具有 90 个属性的 RootObject 类),这仍然会通过 JsonConvert 反序列化,即使我的响应字符串将只引用其中一个属性?
      • @EiEiGuy 看来你可以使用 JsonConverter 抽象类来避免写 90 个属性,但是没有更多示例就很难说更多了...
      • 是的,鉴于此 API,如果所有 90 个属性的响应都具有相同的类引用,并且只有那些具有数据的对象会被转换,那么您将必须创建一个具有 90 个不同属性的 RootObject。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多