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.