使用Newtonsoft.JSON反序列化Drupal JSON时遇SerializationException
执行以下代码时遇到反序列化错误:
App.cmSession.IUSession.equipment = JsonConvert.DeserializeObject<Equipment>(equipJSON);
错误信息:
Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.dll Failed to retrieve Equipment data: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'myProject.Classes.User_Data.Objects.DrupalObject[]' 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. Path 'data[0].relationships.field_equipment_area.data', line 1, position 5372.
已查阅但未解决的相关问题:
- Newtonsoft JsonSerializationException通用排查
- JSON数组与对象类型的反序列化适配问题
- JsonSerializationException典型场景分析
其他注意事项
- JSON结构由第三方提供,无法修改
- 单独序列化Taxonomy对象可成功,推测DrupalObject和Taxonomy代码无问题
- Taxonomy类仅用于避免代码混淆,无扩展功能
- Equipment继承DrupalObject,新增了JSON中独有的需序列化属性
- 尝试将Equipment中的关系字段改为DrupalObject类型,未解决错误
相关类结构
DrupalObject和Equipment类
public class DrupalObject { public DrupalData[] data { get; set; } public DrupalLinks links { get; set; } public DrupalObject() {} } public class Equipment : DrupalObject { public new EquipmentData[] data { get; set; } public Equipment() {} }
支持类定义
// 用于构建Equipment的类设计意图:让Equipment对象包含并序列化DrupalObject的所有字段,以及EquipmentAttributes、EquipmentRelationships等中的自定义字段 public class EquipmentData : DrupalData { public new EquipmentAttributes attributes { get; set;} public new EquipmentRelationships relationships { get; set; } } public class EquipmentAttributes : DrupalAttributes { public int drupal_internal__nid { get; set; } public int drupal_internal__vid { get; set; } public string title { get; set; } public string moderation_state { get; set; } } public class EquipmentRelationships : DrupalRelationships { public DrupalObject[] field_equipment_area { get; set; } public DrupalObject[] field_equipment_category { get; set; } } // 构建DrupalObject的基础类 public class DrupalData { public string type { get; set; } public string id { get; set; } public DrupalLinks links { get; set; } public DrupalAttributes attributes { get; set; } public DrupalRelationships relationships { get; set; } public DrupalMeta meta { get; set; } } public class DrupalAttributes { public int drupal_internal__tid { get; set; } public bool status { get; set; } public string name { get; set; } public object description { get; set; } public DateTime created { get; set; } public DateTime changed { get; set; } } public class DrupalRelationships { public Taxonomy parent { get; set; } }
JSON示例数据
单条目JSON示例
{ "jsonapi": { "version": "1.0", "meta": { "links": { "self": { "href": "http://jsonapi.org/format/1.0/" } } } }, "data": [ { "type": "node--equipment", "id": "2caa087b-949d-455b-a146-a5f31dff5249", "links": { "self": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249?resourceVersion=id%3A970" } }, "attributes": { "drupal_internal__nid": 415, "drupal_internal__vid": 970, "langcode": "en", "revision_timestamp": "2023-04-25T01:12:32+00:00", "revision_log": null, "status": true, "title": "test23", "created": "2023-04-25T01:12:32+00:00", "changed": "2023-04-25T01:12:32+00:00", "promote": true, "sticky": false, "default_langcode": true, "revision_translation_affected": true, "moderation_state": "published", "path": { "alias": "/equipment/test23", "pid": 955, "langcode": "en" }, "field_equipment_name": "test2" }, "relationships": { "node_type": { "data": { "type": "node_type--node_type", "id": "f330b38f-f414-4689-9b7e-11b119673db5", "meta": { "drupal_internal__target_id": "equipment" } }, "links": { "related": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/node_type?resourceVersion=id%3A970" }, "self": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/relationships/node_type?resourceVersion=id%3A970" } } }, "revision_uid": { "data": { "type": "user--user", "id": "fad1cbb3-a0f5-4c42-a516-d2a09178723d", "meta": { "drupal_internal__target_id": 3 } }, "links": { "related": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/revision_uid?resourceVersion=id%3A970" }, "self": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/relationships/revision_uid?resourceVersion=id%3A970" } } }, "field_equipment_area": { "data": null, "links": { "related": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/field_equipment_area?resourceVersion=id%3A970" }, "self": { "href": "http://mysite.local/jsonapi/node/equipment/2caa087b-949d-455b-a146-a5f31dff5249/relationships/field_equipment_area?resourceVersion=id%3A970" } } } } } ], "links": { "next": { "href": "http://mysite.local/jsonapi/node/equipment?page%5Boffset%5D=1&page%5Blimit%5D=1" }, "self": { "href": "http://mysite.local/jsonapi/node/equipment?page%5Blimit%5D=1&page%5Boffset%5D=0" } } }
field_equipment_area有数据时的结构
"field_equipment_area": { "data": { "type": "taxonomy_term--equipment_areas", "id": "497316c8-183c-49d2-a994-d2bcd6ddabe6", "meta": { "drupal_internal__target_id": 542 } } }
内容的提问来源于stack exchange,提问作者Mark L

