简体   繁体   中英

Deserialize a JObject to a list of .NET objects

The task I have is to parse JSON into objects which can then create a form. This form can have sub-forms within it and it is this step I am having difficulty with. Consider this JObject which is a representation of the sub-form and, because the main form has already been deserialized, is now passed as a JObject:

  {
  "3705": {
    "type": "radioGroup",
    "label": "Loft Insulation Applicable",
    "default_value": null,
    "order": "2",
    "required": "false",
    "security": "false",
    "option": null,
    "child": [
      {
        "type": "radio",
        "label": "No",
        "order": "3"
      },
      {
        "type": "radio",
        "label": "Yes",
        "order": "4"
      }
    ]
  },
  "3708": {
    "type": "input",
    "label": "Existing Depth (mm)",
    "default_value": null,
    "order": "5",
    "required": "false",
    "security": "false",
    "option": null
  },
  "3709": {
    "type": "input",
    "label": "Required Depth (mm)",
    "default_value": null,
    "order": "6",
    "required": "false",
    "security": "false",
    "option": null
  },
  "3715": {
    "type": "radioGroup",
    "label": "Total Pipework Meterage",
    "default_value": null,
    "order": "16",
    "required": "false",
    "security": "false",
    "option": null,
    "child": [
      {
        "type": "radio",
        "label": "15 mm",
        "order": "17"
      },
      {
        "type": "radio",
        "label": "22 mm",
        "order": "18"
      },
      {
        "type": "radio",
        "label": "28 mm",
        "order": "19"
      }
    ]
  },
  "3719": {
    "type": "formLabel",
    "label": "Loft Access Requirements",
    "default_value": null,
    "order": "20",
    "required": "false",
    "security": "false",
    "option": null
  },
  "3720": {
    "type": "radioGroup",
    "label": "Crawlers",
    "default_value": null,
    "order": "21",
    "required": "false",
    "security": "false",
    "option": null,
    "child": [
      {
        "type": "radio",
        "label": "No",
        "order": "22"
      },
      {
        "type": "radio",
        "label": "Yes",
        "order": "23"
      }
    ]
  },
  "3723": {
    "type": "radioGroup",
    "label": "Cavity Ladders for Loft",
    "default_value": null,
    "order": "24",
    "required": "false",
    "security": "false",
    "option": null,
    "child": [
      {
        "type": "radio",
        "label": "No",
        "order": "25"
      },
      {
        "type": "radio",
        "label": "Yes",
        "order": "26"
      }
    ]
  },
  "3726": {
    "type": "image",
    "label": "Loft Photos",
    "default_value": null,
    "order": "27",
    "required": "false",
    "security": "false",
    "option": null
  }
}

I am trying to Deserialize it to a list of objects of types defined in this class:

public class DBFormField
{
    public string type { get; set; }
    public string label { get; set; }
    public string default_value { get; set; }
    public string order { get; set; }
    public string required { get; set; }
    public DBFormFieldOption option = new DBFormFieldOption();
    public List<DBFormFieldChild> child = new List<DBFormFieldChild>();
}

public class DBFormFieldOption
{
    public List<DBFormFieldGrid> grid_rows = new List<DBFormFieldGrid>();
    public List<DBFormFieldGrid> grid_columns = new List<DBFormFieldGrid>();
    public string label1 { get; set; }
    public string label2 { get; set; }
    public string result_label { get; set; }
    public string operation { get; set; }
    public List<string> rows = new List<string>();
    public string tab_id { get; set; }
}

public class DBFormFieldChild
{
    public string type { get; set; }
    public string label { get; set; }
    public string order { get; set; }
}

public class DBFormFieldGrid
{
    public string title { get; set; }
    public string name { get; set; }
}

I have tried a few strategies to do this. The latest, I was trying this http://james.newtonking.com/json/help/CustomCreationConverter

For example:

List<DBFormField> parsedFields = new List<DBFormField>();
parsedFields = JsonConvert.DeserializeObject<List<DBFormField>>(someFormObj.form_fields.ToString, new FormConverter());  // ToString???

... Public Class FormConverter Inherits Converters.CustomCreationConverter(Of DBFormField)

    Public Overrides Function Create(objectType As Type) As DBFormField
        Return New DBFormField()
    End Function
End Class

I suspect putting .ToString on the end of the JObject is not good enough for the DeserializeObject method? See comment above. But this code throws the error...

Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'System.Collections.Generic.List`1[RSAP.DBFormField]' because the type requires a JSON array (eg [1,2,3]) to deserialize correctly.

I haven't tried serialising the JObject to a JSON string- this seems daft considering we have already parsed the JSON into a Jobject.

You've got single object in json and you try to deserialize it to list of objects - that can not be done.

Solutions:

  1. You can wrap json object in array by adding [ and ] around object
  2. You can deserialize to single object (not list):

    JsonConvert.DeserializeObject<DBFormField>(someFormObj.form_fields.ToString(), new FormConverter());

  3. You can deserialize single object and add it to list:

    List<DBFormField> parsedFields = new List<DBFormField>(); parsedField = JsonConvert.DeserializeObject<DBFormField>someFormObj.form_fields.ToString(), new FormConverter()); parsedFields.Add(parsedField);

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