嵌套的List属性导致在C#中反序列化时出现问题



我花了一整天的时间引用了许多帖子,并尝试了各种不同的技术来解决这个问题,但都无济于事。我的失败可能只是缺乏理解的结果,但我以前从未经历过这种问题,所以我陷入了某种僵局。

给定以下JSON作为从WebService请求接收的字符串。。。

{
"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": []
}, {
... 
}, {
... 
}]
}

当我尝试反序列化联系人列表时。。。

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
});

我收到错误消息。。。

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

以下类表示JSON反序列化为的。。。

[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; }
}

问题似乎是Newtonsoft希望将HSContactIdentityProfile实例反序列化为Array,即使它实际上是一个对象。属性"Identities"是一个数组,由于它似乎被调用了,我认为这会干扰去序列化过程。然而,我不明白为什么它不将List反序列化为HSContactIdentityProfile对象的属性。

我尝试过自定义转换器,但可能做得不正确(第一次这样做(。我不知道还能尝试什么。在尝试实现其他潜在重复帖子中提出的5或6个"修复"后,我一直无法解决它

根据错误消息:

[DataMember(Name = "identities")]
public Companies.Models.HSContactIdentityProfile IdentityProfiles { get; }

应该是一个列表或数组:

[DataMember(Name = "identities")]
public List<Companies.Models.HSContactIdentityProfile> IdentityProfiles { get; }

如果原始JSON是:,则原始代码可以工作

"contacts": { "identities"

但遗憾的是它是"contacts": [{ "identities"

(额外的[表示涉及JSON数组(

最新更新