如何在 C# 中使用嵌套动态键数组反序列化 json

How to deserialize json with nest array of dynamic keys in C#

我有以下 json 来自 api return 的结构:

{
  "firstName": "test first",
  "lastName": "test last",
  "moduleReports": [
    {
      "completion": "Nothing shared",
      "thoughts": "example",
      "componentTitle": "CareerCorner"
    },
    {
      "thoughts": "example",
      "componentTitle": "CareerLIbrary"
    },
    {
      "completionDate": "0001-01-01T00:00:00",
      "componentTitle": "Discoverer"
    },
    {
      "completionDate": "0001-01-01T00:00:00",
      "componentTitle": "Explorer"
    },
    {
      "workValues": [
        "independence",
        "relationships"
      ],
      "componentTitle": "Navigator"
    },
    {
      "personalityTypes": [
        "Creator",
        "Doer"
      ],
      "componentTitle": "Pathfinder"
    },
    {
      "reflection": "example",
      "completionDate": "0001-01-01T00:00:00",
      "componentTitle": "QuickPic"
    },
    {
      "careerGroup": "Ideas",
      "componentTitle": "Scout"
    },
    {
      "improveAtSkills": [
        "listen",
        "speak"
      ],
      "goodAtSkills": [
        "decision",
        "solve"
      ],
      "componentTitle": "Trekker"
    }
  ]
}

我尝试自己创建 类 并想出了

public class ModuleReport
  {
    public string completion { get; set; }
    public string thoughts { get; set; }
    public string componentTitle { get; set; }
    public DateTime? completionDate { get; set; }
    public List<string> workValues { get; set; }
    public List<string> personalityTypes { get; set; }
    public string reflection { get; set; }
    public string careerGroup { get; set; }
    public List<string> improveAtSkills { get; set; }
    public List<string> goodAtSkills { get; set; }
  }

  public class ModuleResult
  {
    public string firstName { get; set; }
    public string lastName { get; set; }
    public List<ModuleReport> moduleReports { get; set; }
  }

但是当我打电话时

var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString );

在控制器中我得到以下错误

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[...Reports.User.ModuleResults]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

我已尝试按照此处答案中的建议进行操作: and here 但我总是遇到同样的错误。

我开始构建以下内容

public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
    {
      var responseObject = JObject.Load( reader );

      ModuleResult response = new ModuleResult
      {
        firstName = (string)responseObject[ "firstName" ],
        lastName = (string)responseObject[ "lastName" ],
      };

      var varData = new Dictionary<string, object>();

      foreach ( var property in responseObject.Properties() )
      {
        if ( property.Name == "firstName" || property.Name == "lastName" )
        {
          continue;
        }

        varData.Add( property.Name, property.Value );
      }

      response.VarData = varData;
      return response;
    }

但是当我把它放到位时,我意识到它只会将整个“moduleResults”节点添加为 键及其所有内容作为值。回到第一个问题。

我知道问题是访问“moduleReports”json 数组并正确反序列化那些 key/value 对,但我有一段时间想弄清楚如何深入研究它嵌套数组,然后如何处理不断变化的 key/value 对。

当您提供的 JSON 结构表明它是单个 ModuleResult 对象时,为什么要将其反序列化为 List<ModuleResult>

改变一下

var mResults = JsonConvert.DeserializeObject<List<ModuleResult>>( jsonString ); 

var mResults = JsonConvert.DeserializeObject<ModuleResult>( jsonString ); 

它会被正确反序列化。

试试这个

var jD = JsonConvert.DeserializeObject<Root>(json);

output=JsonConvert.SerializeObject(jD); 

输出

{"firstName":"test first","lastName":"test last","moduleReports":[{"completion":"Nothing shared","thoughts":"example","componentTitle":"CareerCorner"},{"thoughts":"example","componentTitle":"CareerLIbrary"},{"componentTitle":"Discoverer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Explorer","completionDate":"0001-01-01T00:00:00-03:30"},{"componentTitle":"Navigator","workValues":["independence","relationships"]},{"componentTitle":"Pathfinder","personalityTypes":["Creator","Doer"]},{"componentTitle":"QuickPic","completionDate":"0001-01-01T00:00:00-03:30","reflection":"example"},{"componentTitle":"Scout","careerGroup":"Ideas"},{"componentTitle":"Trekker","improveAtSkills":["listen","speak"],"goodAtSkills":["decision","solve"]}]}

public partial class Root
    {
        [JsonProperty("firstName")]
        public string FirstName { get; set; }

        [JsonProperty("lastName")]
        public string LastName { get; set; }

        [JsonProperty("moduleReports")]
        public ModuleReport[] ModuleReports { get; set; }
    }

    public partial class ModuleReport
    {
        [JsonProperty("completion", NullValueHandling = NullValueHandling.Ignore)]
        public string Completion { get; set; }

        [JsonProperty("thoughts", NullValueHandling = NullValueHandling.Ignore)]
        public string Thoughts { get; set; }

        [JsonProperty("componentTitle")]
        public string ComponentTitle { get; set; }

        [JsonProperty("completionDate", NullValueHandling = NullValueHandling.Ignore)]
        public DateTimeOffset? CompletionDate { get; set; }

        [JsonProperty("workValues", NullValueHandling = NullValueHandling.Ignore)]
        public string[] WorkValues { get; set; }

        [JsonProperty("personalityTypes", NullValueHandling = NullValueHandling.Ignore)]
        public string[] PersonalityTypes { get; set; }

        [JsonProperty("reflection", NullValueHandling = NullValueHandling.Ignore)]
        public string Reflection { get; set; }

        [JsonProperty("careerGroup", NullValueHandling = NullValueHandling.Ignore)]
        public string CareerGroup { get; set; }

        [JsonProperty("improveAtSkills", NullValueHandling = NullValueHandling.Ignore)]
        public string[] ImproveAtSkills { get; set; }

        [JsonProperty("goodAtSkills", NullValueHandling = NullValueHandling.Ignore)]
        public string[] GoodAtSkills { get; set; }
    }