ghoston3rd
ghoston3rd

Reputation: 149

Cannot deserialize JSON object in C#

I'm trying to deserialize the following JSON string in C#:

{
  "class": [
    "collection",
    "Request"
  ],
  "properties": {
    "total_hits": 61,
    "total_pages": 61,
    "previous_page": null,
    "next_page": 2,
    "current_page": 1,
    "per_page": 1,
    "params": {
      "limit": "1",
      "client_ids": "1001",
      "is_open": "true"
    }
  },
  "entities": [
    {
      "class": [
        "object",
        "Request"
      ],
      "rel": "/rels/request",
      "href": "/app/requests/745109",
      "properties": {
        "id": 745109,
        "name": "Sidewalk/Curb Repair - 628128",
        "description": "651032 STrevino - We live on a corner lot.  The sidewalks have become increasingly uneven over time, causing standing water at multiple places on the sidewalks.  This also often creates standing mud on the sidewalk particularly after rain.\r\n\r\nCould you please request that they be leveled back to be smooth and even and allow for proper drainage?\r\n\r\nThank Very Much,\r\nAllan Meyer\r\n281-380-7012",
        "created_at": "2015-02-24T02:21:41.000Z",
        "updated_at": "2016-05-06T14:14:53.684Z",
        "creator_id": 1110277,
        "permissions": "This is visible to Sugar Land",
        "comments_count": 12,
        "is_current_user_commenter": false,
        "follows_count": 1,
        "is_current_user_following": false,
        "flags_count": 0,
        "is_current_user_flagger": false,
        "tags_count": 0,
        "average_rating": 0,
        "ratings_count": null,
        "object_fields": [
          {
            "id": 7096,
            "name": "Subdivision (if applicable)",
            "description": "",
            "created_at": "2015-08-20T01:26:43.441Z",
            "updated_at": "2015-08-20T01:26:43.441Z",
            "creator_id": null,
            "permissions": "This is visible to Everyone",
            "display_id": 7096,
            "foreign_ids": [],
            "klass": "RequestType",
            "data_type": "STRING",
            "is_allow_null": false,
            "render_guide": "TEXT",
            "default_value": null,
            "default_permissions": {
              "read": [
                707318
              ],
              "write": [
                707318
              ]
            },
            "object_field_options": []
          },
          {
            "id": 7097,
            "name": "Your Street Number and Street Name (if different location)",
            "description": "",
            "created_at": "2015-08-20T01:26:43.466Z",
            "updated_at": "2015-08-20T01:26:43.466Z",
            "creator_id": null,
            "permissions": "This is visible to Everyone",
            "display_id": 7097,
            "foreign_ids": [],
            "klass": "RequestType",
            "data_type": "STRING",
            "is_allow_null": true,
            "render_guide": "TEXT",
            "default_value": null,
            "default_permissions": {
              "read": [
                707318
              ],
              "write": [
                707318
              ]
            },
            "object_field_options": []
          },
          {
            "id": 7095,
            "name": "Your Contact Number",
            "description": "",
            "created_at": "2015-08-20T01:26:43.420Z",
            "updated_at": "2015-08-20T01:26:43.420Z",
            "creator_id": null,
            "permissions": "This is visible to Everyone",
            "display_id": 7095,
            "foreign_ids": [],
            "klass": "RequestType",
            "data_type": "STRING",
            "is_allow_null": false,
            "render_guide": "TEXT",
            "default_value": null,
            "default_permissions": {
              "read": [
                707318
              ],
              "write": [
                707318
              ]
            },
            "object_field_options": []
          },
          {
            "id": 7094,
            "name": "Your Name",
            "description": "",
            "created_at": "2015-08-20T01:26:43.395Z",
            "updated_at": "2015-08-20T01:26:43.395Z",
            "creator_id": null,
            "permissions": "This is visible to Everyone",
            "display_id": 7094,
            "foreign_ids": [],
            "klass": "RequestType",
            "data_type": "STRING",
            "is_allow_null": false,
            "render_guide": "TEXT",
            "default_value": null,
            "default_permissions": {
              "read": [
                707318
              ],
              "write": [
                707318
              ]
            },
            "object_field_options": []
          }
        ],
        "object_field_instances": [
          {
            "id": 702607,
            "name": null,
            "description": null,
            "created_at": "2015-02-24T13:12:15.000Z",
            "updated_at": "2015-08-20T04:14:39.720Z",
            "permissions": "This is visible to Sugar Land",
            "value": "Magnolia Plantation",
            "object_field_id": 7096
          },
          {
            "id": 702606,
            "name": null,
            "description": null,
            "created_at": "2015-02-24T13:12:15.000Z",
            "updated_at": "2015-08-20T04:14:39.702Z",
            "permissions": "This is visible to Sugar Land",
            "value": "2811 Grassy Knoll Ct.",
            "object_field_id": 7097
          },
          {
            "id": 702605,
            "name": null,
            "description": null,
            "created_at": "2015-02-24T13:12:15.000Z",
            "updated_at": "2015-08-20T04:14:39.682Z",
            "permissions": "This is visible to Sugar Land",
            "value": "281-380-7012",
            "object_field_id": 7095
          },
          {
            "id": 702604,
            "name": null,
            "description": null,
            "created_at": "2015-02-24T13:12:15.000Z",
            "updated_at": "2015-08-20T04:14:39.664Z",
            "permissions": "This is visible to Sugar Land",
            "value": "Allan Meyer",
            "object_field_id": 7094
          }
        ],
        "display_id": 745109,
        "foreign_ids": [],
        "status": "IN_PROGRESS",
        "priority": "MEDIUM",
        "request_type_id": 29119,
        "geo_location_id": 686866,
        "workflow_node_id": 890541,
        "workflow_graph_id": 706096,
        "completed_at": "2015-02-25T16:13:17.000Z",
        "due_at": "2016-05-10T05:00:00.000Z",
        "due_status": "OPEN",
        "client_id": 1001,
        "display_foreign_id": false,
        "api_source_id": 15,
        "is_duplicate": false,
        "is_self_closure_allowed": true,
        "has_duplicates": false,
        "use_permission_matrix": true,
        "request_type_foreign_api_ids": [],
        "primary_attachment_id": null,
        "attachments_count": 0,
        "primary_attachment": null,
        "contact_info": {
          "name": "Allan Meyer",
          "full_name": "Allan Meyer",
          "first_name": "Allan",
          "last_name": "Meyer",
          "username": "allanrmeyer",
          "phone": "",
          "email": "[email protected]",
          "user_id": 1110277
        },
        "geo_location": {
          "id": 686866,
          "name": "2811 Grassy Knoll Court, Sugar Land, TX 77478, USA",
          "description": null,
          "created_at": "2015-08-20T04:06:13.717Z",
          "updated_at": "2015-08-20T04:06:13.717Z",
          "creator_id": null,
          "permissions": "This is visible to Everyone",
          "geo_data_id": 738892,
          "postal_address_id": 682944,
          "accuracy_m": null,
          "latitude": 29.585971,
          "longitude": -95.587433,
          "geo_location": {},
          "postal_address": {
            "id": 682944,
            "name": "2811 Grassy Knoll Court, Sugar Land, TX 77478, USA",
            "description": "2811 Grassy Knoll Court, Sugar Land, TX 77478, USA",
            "created_at": "2015-08-20T04:06:13.706Z",
            "updated_at": "2015-08-20T04:06:13.706Z",
            "permissions": "This is visible to Everyone",
            "source": null,
            "street_number": "2811",
            "street_number_unit": null,
            "street_name": "Grassy Knoll Court",
            "postal_code": "77478",
            "region_id": 17622,
            "geo_data_id": null,
            "intersection": null,
            "formatted_address": "2811  Grassy Knoll Court"
          }
        },
        "request_type_name": "Sidewalk/Curb Repair",
        "creator_display_name": "Allan Meyer",
        "api_source_name": "Iframe"
      },
      "actions": []
    }
  ],
  "actions": [],
  "links": [
    {
      "rel": [
        "self"
      ],
      "href": "/app/requests?page=1&limit=1&sort_dir=asc&client_ids=1001&is_open=true"
    },
    {
      "rel": [
        "next"
      ],
      "href": "/app/requests?page=2&limit=1&sort_dir=asc&client_ids=1001&is_open=true"
    }
  ]
}

I've created the following RootObject class to map the JSON:

 public class RootObject
        {
            public List<string> @class { get; set; }
            public Properties2 properties { get; set; }
            public List<Entity> entities { get; set; }
            public List<object> actions { get; set; }
            public List<Link> links { get; set; }
        }

Previously the following code was working to deserialize the JSON into the RootObject:

 var objResponse1 = JsonConvert.DeserializeObject<RootObject>(response2.Content);

However, my code is now throwing a JSON.net exception:

An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ProcessOpenRequests.Program+RootObject]' 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) 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.

Now, I have tried the following to deserialize the JSON string based on other StackOverflow posts in regards to this error but the error has persisted:

var test = JsonConvert.DeserializeObject<List<RootObject>>(response2.Content);

Any help would be greatly appreciated. Thanks!

*Updated

Here is the Entity class:

public class Entity
        {
            public List<string> @class { get; set; }
            public string rel { get; set; }
            public Properties2 properties { get; set; }
            public Actions actions { get; set; }
        }

And here is the Properties2 class:

public class Properties2
        {
            public int? id { get; set; }
            public string name { get; set; }
            public string description { get; set; }
            public string created_at { get; set; }
            public string updated_at { get; set; }
            public int? creator_id { get; set; }
            public string permissions { get; set; }
            public int? comments_count { get; set; }
            public bool is_current_user_commenter { get; set; }
            public int? follows_count { get; set; }
            public bool is_current_user_following { get; set; }
            public int? flags_count { get; set; }
            public bool is_current_user_flagger { get; set; }
            public int? tags_count { get; set; }
            public decimal average_rating { get; set; }
            public object ratings_count { get; set; }
            public List<ObjectField> object_fields { get; set; }
            public List<ObjectFieldInstance> object_field_instances { get; set; }
            public int? display_id { get; set; }
            public List<object> foreign_ids { get; set; }
            public string status { get; set; }
            public string priority { get; set; }
            public int? request_type_id { get; set; }
            public int? geo_location_id { get; set; }
            public int? workflow_node_id { get; set; }
            public int? workflow_graph_id { get; set; }
            public object completed_at { get; set; }
            public string due_at { get; set; }
            public string due_status { get; set; }
            public int? client_id { get; set; }
            public bool display_foreign_id { get; set; }
            public int? api_source_id { get; set; }
            public bool is_duplicate { get; set; }
            public bool is_self_closure_allowed { get; set; }
            public bool has_duplicates { get; set; }
            public bool use_permission_matrix { get; set; }
            public List<object> request_type_foreign_api_ids { get; set; }
            public object primary_attachment_id { get; set; }
            public int? attachments_count { get; set; }
            public object primary_attachment { get; set; }
            public ContactInfo contact_info { get; set; }
            public GeoLocation geo_location { get; set; }
            public string request_type_name { get; set; }
            public string creator_display_name { get; set; }
            public string api_source_name { get; set; }
        }

Upvotes: 0

Views: 6326

Answers (2)

ghoston3rd
ghoston3rd

Reputation: 149

So, here's what happened, the API I was receiving the JSON data from changed up the RootObject and where I was previously referencing Properties2, I needed to change that to reference Properites. I also had to change a bunch of integers to now receive null data. My original code to deserialize the RootObject (and Bruno Garcia's answer) is valid once again.

Upvotes: 0

Bruno Garcia
Bruno Garcia

Reputation: 6398

You are trying to deserialize your JSON into a List<RootObject>. That requires your JSON to be an array, but your JSON is not an array, JSON arrays begin and end with [ and ].

Try desalinizing to a RootObject instead.

var test = JsonConvert.DeserializeObject<RootObject>(response2.Content);

Upvotes: 3

Related Questions