I have spent all day referencing numerous posts and trying all sorts of different techniques for resolving this issue, to no avail. My failures may just be the result of a lack of understanding, but I have never experienced this kind of problem before so I have arrived at something of an impasse.
Given the following JSON as a string received from a WebService request ...
{
"contacts": [{
"identities": [{
"vid": 40451,
"identity": [{
"value": "bsmith#aol.com",
"type": "EMAIL",
"timestamp": 4556668881236,
"isPrimary": true
},
{
"value": "a2c53333-3333-3333-3333-34bc21723333",
"type": "LEAD_GUID",
"timestamp": 4556668881236
}],
"linkedVid": []
}],
"properties": [{
"name": "firstname",
"value": "Bob",
"sourceVid": []
},
{
"name": "lastmodifieddate",
"value": "151512112212",
"sourceVid": []
},
{
"name": "lastname",
"value": "Smith",
"sourceVid": []
}],
"formSubmissions": [],
"listMembership": [],
"vid": 44444,
"portalId": 4444444,
"isContact": true,
"vids": [],
"imports": [],
"publicToken": "kshdfkjhsdsdjfjkdhshjksd",
"canonicalVid": 44444,
"mergeAudit": [],
"mergedVids": [],
"campaigns": [],
"stateChanges": []
}, {
...
}, {
...
}]
}
When I try to deserialize the list of contacts ...
String jsonString = obj.GetJson();
var response = Newtonsoft.Json.JsonConvert.DeserializeObject<HSContactListResult>(
jsonString,
new Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
});
I get the error message ...
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'HSContactIdentityProfile' 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 'contacts[0].identities', line 1, position 28
The following classes represent the which the JSON is deserialized into ...
[Serializable]
[DataContract]
public class HSContactListResult
{
[DataMember(Name ="hasMore")]
public bool HasMore { get; set; }
[DataMember(Name = "vidOffset")]
public long Offset { get; set; }
[DataMember(Name = "contacts")]
public List<Companies.Models.HSContact> Contacts{ get; set; }
public Int32 Count { get { return this.Contacts.Count; } }
public HSContactListResult()
{
this.Contacts = new List<Companies.Models.HSContact>().ToList();
}
}
[Serializable]
[DataContract]
public class HSContact
{
[DataMember(Name = "vid")]
public long ContactId { get; set; }
[DataMember(Name = "portalId")]
public long PortalId { get; set; }
[DataMember(Name = "isContact")]
public bool IsContact { get; set; }
[DataMember(Name = "properties")]
public Companies.Models.HSContactProperties Properties { get; set; }
[DataMember(Name = "identities")]
public Companies.Models.HSContactIdentityProfile IdentityProfiles { get; }
public HSCompany Company { get; set; }
#region c-tor
public HSContact()
{
this.Properties = new Companies.Models.HSContactProperties();
this.IdentityProfiles = new Companies.Models.HSContactIdentityProfile();
}
#endregion c-tor
}
[Serializable]
[DataContract]
public class HSContactProperties: IHSContactProperties
{
[DataMember(Name ="firstname")]
public HSProperty FirstName { get; set; }
[DataMember(Name = "lastname")]
public HSProperty LastName { get; set; }
[DataMember(Name = "company")]
public HSProperty CompanyName { get; set; }
}
[Serializable]
[DataContract]
public class HSContactIdentityProfile
{
[DataMember(Name = "vid")]
public Int64 ContactID { get; set; }
[DataMember(Name = "identity")]
public List<Companies.Models.HSContactIdentity> Identities { get; set; }
[DataMember(Name = "saved-at-timestamp")]
public Int64 saved_at_timestamp { get; set; }
[DataMember(Name = "deleted-changed-timestamp")]
public Int64 deleted_changed_timestamp { get; set; }
public HSContactIdentityProfile()
{
this.Identities = new List<Companies.Models.HSContactIdentity>().ToList();
}
}
[Serializable]
[DataContract]
public class HSContactIdentity : IHSContactIdentity
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "value")]
public string Value { get; set; }
[DataMember(Name = "timestamp")]
public long Timestamp { get; set; }
[DataMember(Name = "isPrimary")]
public bool IsPrimary { get; set; }
}
The problem appears to be that Newtonsoft wants to deserialize the HSContactIdentityProfile instance into an Array even though it's actually an object. The property "Identities" IS an array and since it seems to be cvalled out I am assuming that that is interfering with the desrialization process. I don't understand however why it's just not deserializing the List as a property of the HSContactIdentityProfile object.
I have tried custom converters but may have done those incorrectly (first time with this). I am not sure what else to try.
After trying to implement 5 or 6 of the "fixes" presented in other potential duplicate posts I have not been able to resolve it.
As per the error message:
[DataMember(Name = "identities")]
public Companies.Models.HSContactIdentityProfile IdentityProfiles { get; }
should be a list or array:
[DataMember(Name = "identities")]
public List<Companies.Models.HSContactIdentityProfile> IdentityProfiles { get; }
Your original code would work if the original JSON was:
"contacts": {
"identities"
but alas it is "contacts": [{
"identities"
(the extra [ meaning a JSON array is involved)
Related
I am having trouble with deserializing data from a JSON string:
[{
"Example A": [{
"Parameter1": "Example A",
"Parameter2": "aaa",
"Parameter3": "2022-06-30 21:15:00.0000000",
"Value": 11.11
}
],
"Example B": [{
"Parameter1": "Example B",
"Parameter2": "ccc",
"Parameter3": "2022-06-30 21:15:00.0000000",
"Value": 33.33
}
],
"Example C": [
{
"Parameter1": "Example C",
"Parameter2": "eee",
"TimestampUTC": "2022-06-30 21:15:00.0000000",
"Value": null
},
{
"Parameter1": "Example C",
"Parameter2": "fff",
"Parameter3": "2022-06-30 21:15:00.0000000",
"Value": 44.44
}
]
}]
What I have tried is:
public class ExampleA
{
public string Parameter1 { get; set; }
public string Parameter2 { get; set; }
public string Parameter3 { get; set; }
public double Value { get; set; }
}
public class ExampleB
{
public string Parameter1 { get; set; }
public string Parameter2 { get; set; }
public string Parameter3 { get; set; }
public double Value { get; set; }
}
public class ExampleC
{
public string Parameter1 { get; set; }
public string Parameter2 { get; set; }
public string Parameter3 { get; set; }
public double Value { get; set; }
}
public class Examples
{
[JsonProperty("Example A")]
public List<ExampleA> ExampleA { get; set; }
[JsonProperty("Example B")]
public List<ExampleB> ExampleB { get; set; }
[JsonProperty("Example C")]
public List<ExampleC> ExampleC { get; set; }
}
But when I try to test it with this:
Examples someVar = JsonConvert.DeserializeObject<Examples>(JsonString);
Console.WriteLine(SomeVar.ExampleA.Count);
I get this error:
Unhandled exception. Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MyProject.Examples' 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.
Apparently I have trouble understanding how deserialization works - what I want to do with this is something like this:
foreach item in Example
// do something
foreach thing in item
// do something more
I realise I have some trouble with grasping the JSON format in this case.
I'm using .NET Core.
you have an array in your json Try this
List<Examples> someVar = JsonConvert.DeserializeObject<List<Examples>>(JsonString);
I have little to no experience in JSON and I am stuck with a problem. Any help is appreciated.
I want to access specifically the names' values from the additionalInformation array.
JSON Response:
{
"statusCode": 200,
"version": 1,
"jsonData": [
{
"additionalInformation": [
{
"id": "XXX94XXXX9xxXx_xxxXXXX",
"name": "xxxx xxx x xxxxxxxx"
},
{
"id": "0xXXxcXxv5PQqT$6i2zLgV",
"name": "xxx xxxxxxxx"
},
{
"id": "11Krt_our2rPCPqJ_2fKZR",
"name": "xxx xxxxxxxx xx"
},
{
"id": "2jYw4IyBP8KuozM_ej7DGf",
"name": "xxxxxxx 1"
},
{
"id": "3B8O805wL1ufabHMz1Je3v",
"name": "xxxxxxx 2"
},
{
"id": "0FVKUYZkvFaxd_OQUiyPBZ",
"name": "xxxxxxx"
},
{
"id": "3O41QFd0573QQvFco5zUUP",
"name": "Xxxxxxxxx"
}
],
"type": 0
}
],
"errorMessages": [],
"warningMessages": [],
"informationMessages": []
}
Model:
public class CFunctions
{
public int statusCode { get; set; }
public int version { get; set; }
public List<PFunctions>[] jsonData { get; set; }
public List<string> errorMessages { get; set; }
public List<string> warningMessages { get; set; }
public List<string> informationMessages { get; set; }
/*public CFunctions()
{
jsonData = new List<PFunctions>();
}*/
}
[Serializable]
public class PFunctions
{
public List<PAdditionalInfo>[] additionalInformation { get; set; }
public int type { get; set; }
/*public PFunctions()
{
additionalInformation = new List<PAdditionalInfo>();
}*/
}
[Serializable]
public class PAdditionalInfo
{
public Guid id { get; set; }
public string name { get; set; }
}
Deserialisation
var request = UnityWebRequest.Get(baseurl);
var operation = request.SendWebRequest();
var jsonResponse = request.downloadHandler.text;
List<CFunctions>[] PFunctionsList = JsonConvert.DeserializeObject<List<CFunctions>[]>(jsonResponse);
Error:
Cannot deserialize the current JSON object into type 'System.Collections.Generic.List`1[CFunctions][]' because the type requires a JSON array to deserialize correctly.
To fix this error either change the JSON to a JSON array or change the deserialized type so that it is a normal .NET type 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.
Path 'statusCode', line 1, position 14.
UnityEngine.Debug:Log(Object)
What I tried
The error pertains even when I changed List<PAdditionalInfo> to List<PAdditionalInfo>[]
I am not sure how to use JsonObjectAttribute and if it is the best way.
You've declared an array of List<T> in the models, eg List<PAdditionalInfo>[]. The json represents single arrays, not nested. You can fix that by choosing one or the other (I decided to use List<> but array is valid too):
public class PFunctions
{
public List<PAdditionalInfo> additionalInformation { get; set; } // removed []
...
}
public class CFunctions
{
public int statusCode { get; set; }
public int version { get; set; }
public List<PFunctions> jsonData { get; set; } // removed []
...
}
The class you're deserializing to is incorrect. Deserialize to the correct type (which is CFunctions not List<CFunctions>[]):
CFunctions cFunctions = JsonConvert.DeserializeObject<CFunctions>(json);
the most efficient way to get an additional information is this one line code and you only need one class
List<AdditionalInformation> additionalInformation = JObject.Parse(json)
["jsonData"][0]["additionalInformation"].ToObject<List<AdditionalInformation>>();
class
public class AdditionalInformation
{
public string id { get; set; }
public string name { get; set; }
}
I am trying to deserialize a JSON response, but I am doing something wrong when creating the data models.
I deserialize normally with EventsData resultJSON = JsonConvert.DeserializeObject<EventsData>(jsonText);
JSON contains list of events such as:
{
"#event_no":"6924",
"#name":"REDACTED",
"Show":{
"#show_no":"1",
"#show_datetime":"2007-04-05 15:00:00"
}
},
{
"#event_no":"6925",
"#name":"REDACTED",
"Show":{
"#show_no":"1",
"#show_datetime":"2007-04-15 15:00:00"
}
}
My data model:
public class Show
{
[JsonProperty("#show_no")]
public string show_no { get; set; }
[JsonProperty("#show_datetime")]
public string show_datetime { get; set; }
}
public class Event
{
[JsonProperty("#event_no")]
public string event_no { get; set; }
[JsonProperty("#name")]
public string name { get; set; }
public Show Show { get; set; }
}
public class Events
{
public List<Event> Event { get; set; }
}
public class EventsData
{
public Events Events { get; set; }
}
However, when I am trying to deserialize I get the following error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type 'VM_Models.Show' 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 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.
What exactly am I doing wrong? If I make the Show property dynamic instead of class Show then it works
UPDATE: I did find in the data sometimes there are more than one shows:
{
"#event_no":"54535",
"#name":"REDACTED",
"Show": [
{
"#show_no": "1",
"#show_datetime": "2009-05-06 19:00:00"
},
{
"#show_no": "2",
"#show_datetime": "2009-05-07 19:00:00"
},
{
"#show_no": "3",
"#show_datetime": "2009-05-08 19:00:00"
},
{
"#show_no": "4",
"#show_datetime": "2009-05-09 19:00:00"
},
{
"#show_no": "5",
"#show_datetime": "2009-05-10 19:00:00"
}
]
}
The problem was I was converting from XML to JSON to Object. I've decided to go from XML to object directly:
[XmlRoot(ElementName = "Show", Namespace = "http://REDACTED/schema")]
public class Show
{
[XmlAttribute(AttributeName = "show_no")]
public string Show_no { get; set; }
[XmlAttribute(AttributeName = "show_datetime")]
public string Show_datetime { get; set; }
}
[XmlRoot(ElementName = "Event", Namespace = "http://REDACTED/schema")]
public class Event
{
[XmlElement(ElementName = "Show", Namespace = "http:/REDACTED/schema")]
public List<Show> Show { get; set; }
[XmlAttribute(AttributeName = "event_no")]
public string Event_no { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "Events", Namespace = "http://REDACTED/schema")]
public class Events
{
[XmlElement(ElementName = "Event", Namespace = "http://REDACTED/schema")]
public List<Event> Event { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
}
Then in the code:
XmlSerializer serializer = new XmlSerializer(typeof(Events));
TextReader reader = new StringReader(response.Content);
Events result = (Events)serializer.Deserialize(reader);
Now I am able to see all data properties normally.
I have below JSON file,
[
{
"applicationConfig": {
"Name": "Name1",
"Site": "Site1"
},
"pathConfig": {
"SourcePath": "C:\\Temp\\Outgoing1",
"TargetPath": "C:\\Files"
},
"credentialConfig": {
"Username": "test1",
"password": "super1"
}
},
{
"applicationConfig": {
"Name": "Name2",
"Site": "Site2"
},
"pathConfig": {
"SourcePath": "C:\\Temp\\Outgoing2",
"TargetPath": "C:\\Files"
},
"credentialConfig": {
"Username": "test2",
"password": "super2"
}
}
]
And below are C# classes structure,
public class Configurations
{
public List<ApplicationConfig> ApplicationConfigs { get; set; }
public List<PathConfig> PathConfigs { get; set; }
public List<CredentialConfig> CredentialConfigs { get; set; }
}
public class ApplicationConfig
{
public string Name { get; set; }
public string Site { get; set; }
}
public class PathConfig
{
public string SourcePath { get; set; }
public string TargetPath { get; set; }
}
public class CredentialConfig
{
public string Username { get; set; }
public string password { get; set; }
}
Now trying to load JSON and getting below error,
using (var streamReader = new StreamReader(#"./Config.json"))
{
var X = JsonConvert.DeserializeObject<Configurations>(streamReader.ReadToEnd());
}
$exception {"Cannot deserialize the current JSON array (e.g. [1,2,3])
into type 'ConsoleApp8.Configurations' because the type requires a
JSON object (e.g. {\"name\":\"value\"}) to deserialize
correctly.\r\nTo 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 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.\r\nPath '', line 1, position
1."} Newtonsoft.Json.JsonSerializationException
What else I need to serialize?
Your JSON represents an array - although the closing [ should be a ]. But you're trying to serialize it into a single Configurations object. Additionally, you seem to be expecting separate arrays for the application configs, path configs and credential configs - whereas your JSON shows an array of objects, each of which has all three.
I suspect you want:
public class Configuration
{
[JsonProperty("applicationConfig")]
ApplicationConfig ApplicationConfig { get; set; }
[JsonProperty("pathConfig")]
PathConfig PathConfig { get; set; }
[JsonProperty("credentialConfig")]
CredentialConfig CredentialConfig { get; set; }
}
// Other classes as before, although preferably with the password property more conventionally named
Then use:
List<Configuration> configurations =
JsonConvert.DeserializeObject<List<Configuration>>(streamReader.ReadToEnd());
You'll then have a list of configuration objects, each of which will have the three "subconfiguration" parts.
Your JSON class definition is close but not quite. Moroever the last [ must be ]
JSON class definition is created wtih QuickType
public partial class Configuration
{
[JsonProperty("applicationConfig")]
public ApplicationConfig ApplicationConfig { get; set; }
[JsonProperty("pathConfig")]
public PathConfig PathConfig { get; set; }
[JsonProperty("credentialConfig")]
public CredentialConfig CredentialConfig { get; set; }
}
public partial class ApplicationConfig
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Site")]
public string Site { get; set; }
}
public partial class CredentialConfig
{
[JsonProperty("Username")]
public string Username { get; set; }
[JsonProperty("password")]
public string Password { get; set; }
}
public partial class PathConfig
{
[JsonProperty("SourcePath")]
public string SourcePath { get; set; }
[JsonProperty("TargetPath")]
public string TargetPath { get; set; }
}
Finally you need to serialize with
var config_list = JsonConvert.DeserializeObject<List<Configuration>>(streamReader.ReadToEnd());
I think it is a typo, you are opening the square bracket instead of closing it in the JSON file.
[ {
"applicationConfig": {
"Name": "Name1",
"Site": "Site1"
},
"pathConfig": {
"SourcePath": "C:\Temp\Outgoing1",
"TargetPath": "C:\Files"
},
"credentialConfig": {
"Username": "test1",
"password": "super1"
} }, {
"applicationConfig": {
"Name": "Name2",
"Site": "Site2"
},
"pathConfig": {
"SourcePath": "C:\Temp\Outgoing2",
"TargetPath": "C:\Files"
},
"credentialConfig": {
"Username": "test2",
"password": "super2"
} } [ <-HERE
My JSON feed has nested objects like this:
{
"id": 1765116,
"name": "StrozeR",
"birth": "2009-08-12",
"avatar": "http:\/\/static.erepublik.com\/uploads\/avatars\/Citizens\/2009\/08\/12\/f19db99e9baddad73981d214a6e576ef_100x100.jpg",
"online": true,
"alive": true,
"ban": null,
"level": 61,
"experience": 183920,
"strength": 25779.42,
"rank": {
"points": 133687587,
"level": 63,
"image": "http:\/\/www.erepublik.com\/images\/modules\/ranks\/god_of_war_1.png",
"name": "God of War*"
},
"elite_citizen": false,
"national_rank": 6,
"residence": {
"country": {
"id": 81,
"name": "Republic of China (Taiwan)",
"code": "TW"
},
"region": {
"id": 484,
"name": "Hokkaido"
}
}
}
and my object classes are like this:
class Citizen
{
public class Rank
{
public int points { get; set; }
public int level { get; set; }
public string image { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public string avatar { get; set; }
public bool online { get; set; }
public bool alive { get; set; }
public string ban { get; set; }
public string birth { get; set; }
public int level { get; set; }
public int experience { get; set; }
public double strength { get; set; }
public List<Rank> rank { get; set; }
}
}
I try to parse my JSON data with following code
private async void getJSON()
{
var http = new HttpClient();
http.MaxResponseContentBufferSize = Int32.MaxValue;
var response = await http.GetStringAsync(uri);
var rootObject = JsonConvert.DeserializeObject<Citizen.RootObject>(response);
uriTB.Text = rootObject.name;
responseDebug.Text = response;
}
but I get the following error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Erepublik.Citizen+Rank]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I can't even parse the value in the main object. Anyway to fix this? and how can I parse a value inside of a nested object? for example: "points" in "rank"
Like the error message says, your rank property in the .NET class is a List<Rank>, but in your JSON it's just a nested object, not an array. Change it to just a Rank instead of a List<Rank>.
Arrays in JSON (or any Javascript, really) are enclosed in []. The {} characters specify a single object. The CLR type has to roughly match the JSON type in order to deserialize. Object to object, array to array.