John John
John John

Reputation: 1

JSON.NET error "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type because the type requires a JSON object (e.g. {"name":"value"})"

I have the following WebCleint to call a Restful web service inside my .net console application:-

try
{
    using (WebClient wc = new WebClient())
    {
        wc.Encoding = Encoding.UTF8;
        string url = "https://*****/paged?hapikey=*********&properties=website&properties=i_scan&limit=2";//web service url
        string tempurl = url.Trim();
        var json = wc.DownloadString(tempurl);//get the json
        Marketing ipfd = JsonConvert.DeserializeObject<Marketing>(json);//deserialize
    }
}
catch (Exception e)
{
    //code goes here..
}

where i am using JSON.Net to Deserialize the json object, which will be as follow:-

{
  "has-more": true,
  "offset": 622438650,
  "companies": [
    {
      "portalId": *******,
      "companyId": *****,
      "isDeleted": false,
      "properties": {
        "website": {
          "value": "****.net",
          "timestamp": 1520938239457,
          "source": "CALCULATED",
          "sourceId": null,
          "versions": [
            {
              "name": "website",
              "value": "*****.net",
              "timestamp": 1520938239457,
              "source": "CALCULATED",
              "sourceVid": [
                731938234
              ]
            }
          ]
        }
      },
      "additionalDomains": [],
      "stateChanges": [],
      "mergeAudits": []
    },
    {
      "portalId": ******,
      "companyId": ******,
      "isDeleted": false,
      "properties": {
        "website": {
          "value": "****.***.***",
          "timestamp": 1512488590073,
          "source": "CALCULATED",
          "sourceId": null,
          "versions": [
            {
              "name": "website",
              "value": "****.***8.****",
              "timestamp": 1512488590073,
              "source": "CALCULATED",
              "sourceVid": []
            }
          ]
        },
        "i_scan": {
          "value": "Yes",
          "timestamp": 1543409493459,
          "source": "******",
          "sourceId": "**************",
          "versions": [
            {
              "name": "i_scan",
              "value": "Yes",
              "timestamp": 1543409493459,
              "sourceId": *****",
              "source": "CRM_UI",
              "sourceVid": [],
              "requestId": "******"
            }
          ]
        }
      },
      "additionalDomains": [],
      "stateChanges": [],
      "mergeAudits": []
    }
  ]
}

Here are my classes:-

public class Marketing
{
    public Companies companies { get; set; }
}

public class Companies
{
    public IList<string> companyId { get; set; }
    public IList<Properties> properties { get; set; }
}

public class Properties
{
    public IList<Website> website { get; set; }
    public IList<I_Scan> i_scan { get; set; }
}

public class Website
{
    public string value { get; set; }
}

public class i_Scan
{
    public string value { get; set; }
}

but currently i am getting this exception, when i try to de-serialize the JSON object:-

Newtonsoft.Json.JsonSerializationException was caught
  HResult=-2146233088
  Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MMarketing.Companies' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'companies', line 1, position 49.
  Source=Newtonsoft.Json
  StackTrace:

so i am not sure why JSON.NET is unable to do the Deserialize correctly, as in my case the classes are compatible with the returned json object??

Upvotes: 1

Views: 742

Answers (2)

Ryan Schlueter
Ryan Schlueter

Reputation: 2221

If I'm coming to json blind I like to use http://json2csharp.com/ to generate my class structure for me

public class Version
{
    public string name { get; set; }
    public string value { get; set; }
    public object timestamp { get; set; }
    public string source { get; set; }
    public List<object> sourceVid { get; set; }
}

public class Website
{
    public string value { get; set; }
    public object timestamp { get; set; }
    public string source { get; set; }
    public object sourceId { get; set; }
    public List<Version> versions { get; set; }
}

public class Version2
{
    public string name { get; set; }
    public string value { get; set; }
    public long timestamp { get; set; }
    public int sourceId { get; set; }
    public string source { get; set; }
    public List<object> sourceVid { get; set; }
    public int requestId { get; set; }
}

public class IScan
{
    public string value { get; set; }
    public long timestamp { get; set; }
    public int source { get; set; }
    public int sourceId { get; set; }
    public List<Version2> versions { get; set; }
}

public class Properties
{
    public Website website { get; set; }
    public IScan i_scan { get; set; }
}

public class Company
{
    public int portalId { get; set; }
    public int companyId { get; set; }
    public bool isDeleted { get; set; }
    public Properties properties { get; set; }
    public List<object> additionalDomains { get; set; }
    public List<object> stateChanges { get; set; }
    public List<object> mergeAudits { get; set; }
}

public class Marketing
{
    public bool has_more { get; set; }
    public int offset { get; set; }
    public List<Company> companies { get; set; }
}

 var result = JsonConvert.DeserializeObject<Marketing>(json);

Upvotes: 0

VDWWD
VDWWD

Reputation: 35564

At a first glance it looks like you switched two properties in Making them a List and vice versa.

public class Marketing
{
    public List<Companies> companies { get; set; }
}

Is "companies": [ in the json, while "companyId": *****, is the id as a string, not array. Properties is not an array also, but the property versions of properties is.

public class Companies
{
    public string companyId { get; set; }
    public Properties properties { get; set; }
}

Upvotes: 1

Related Questions