英文:
Newtonsoft.JSON throwing SerializationException
问题
I am having an issue deserializing some JSON data from a Drupal site to a C# application using the Newtonsoft.JSON package.
Upon running this line of code (where .equipment is an object of type Equipment):
App.cmSession.IUSession.equipment = JsonConvert.DeserializeObject<Equipment>(equipJSON);
This error is thrown:
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.
I reviewed a couple other questions, but they didn't help me directly resolve the issue. Other things of note:
- I can't change my JSON structure, it is 3rd party.
- Taxonomy objects serialize successfully when serialized on their own, so I suspect DrupalObject and Taxonomy are coded correctly.
- Taxonomy is a class made purely to avoid confusion in my code, it doesn't extend other functionality.
- Equipment extends DrupalObject to add some additional properties from the JSON that need to be serialized that are unique to DrupalObject.
- I have tried to change the relationships in Equipment to be DrupalObject, but this did not change anything about the error.
That being said, here is some context of classes being used here:
DrupalObject and 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() {}
}
Supporting classes to DrupalObject and Equipment:
// Classes used for building Equipment (the intent of this is for an Equipment object to contain (and serialize) all fields defined in DrupalObject, as well as the other defined fields in EquipmentAttributes, EquipmentRelationships, etc.
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; }
}
// Classes for building the 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 sample data (one entry only):
{
"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-a5f31dff524
<details>
<summary>英文:</summary>
I am having an issue deserializing some JSON data from a Drupal site to a C# application using the Newtonsoft.JSON package.
Upon running this line of code (where .equipment is an object of type Equipment):
```cs
App.cmSession.IUSession.equipment = JsonConvert.DeserializeObject<Equipment>(equipJSON);
This error is thrown:
> 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<T>) 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.
I reviewed a couple other questions, but they didn't help me directly resolve the issue:
https://stackoverflow.com/questions/70567628/newtonsoft-jsonserializationexception
https://stackoverflow.com/questions/22557559/cannot-deserialize-the-json-array-e-g-1-2-3-into-type-because-type-requ
https://stackoverflow.com/questions/16768577/jsonserializationexception
Other things of note:
-
I can't change my JSON structure, it is 3rd party.
-
Taxonomy objects serialize successfully when serialized on their own,
so I suspect DrupalObject and Taxonomy are coded correctly. -
Taxonomy is a class made purely to avoid confusion in my code, it
doesnt extend other functionality. -
Equipment extends DrupalObject to add some additional properties
from the JSON that need o be serialized that are unique to
DrupalObject. -
I have tried to change the relationships in Equipment to be
DrupalObject, but this did not change anything about the error.
That being said, here is some context of classes being used here:
DrupalObject and Equipment:
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-html -->
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() {}
}
<!-- end snippet -->
Supporting classes to DrupalObject and Equipment:
<!-- begin snippet: js hide: true console: falsebabel: false -->
<!-- language: lang-html -->
// Classes used for building Equipment (the intent of this is for an Equipment object to contain (and serialize) all fields defined in DrupalObject, as well as the other defined fields in EquipmentAttributes, EquipmentRelationships, etc.
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; }
}
// Classes for building the 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; }
}
<!-- end snippet -->
JSON sample data (one entry only):
{
"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"
}
}
}
I should also note that it is normal for field_equipment_area to sometimes have that null value if nothing is associated with that. Otherwise it would look like this:
"field_equipment_area": {
"data": {
"type": "taxonomy_term--equipment_areas",
"id": "497316c8-183c-49d2-a994-d2bcd6ddabe6",
"meta": {
"drupal_internal__target_id": 542
}
答案1
得分: 1
以下是您要翻译的内容:
"It is hard to understand from your code how classes are depended. It seems to me that the classes and a json strig are completely different. This code works. You can add "Drupal" prefix to the classes and properties that you want"
"从您的代码中很难理解类之间的依赖关系。在我看来,类和 JSON 字符串似乎完全不同。这段代码有效。您可以为您想要的类和属性添加“Drupal”前缀。"
英文:
It is hard to understand from your code how classes are depended. It seems to me that the classes and a json strig are completely different. This code works. You can add "Drupal" prefix to the classes and properties that you want
JsonConvert.DeserializeObject<Equipment>(json);
public class Equipment
{
public Jsonapi jsonapi { get; set; }
public List<Data> data { get; set; }
public Links links { get; set; }
}
public class Attributes
{
public int drupal_internal__nid { get; set; }
public int drupal_internal__vid { get; set; }
public string langcode { get; set; }
public DateTime revision_timestamp { get; set; }
public object revision_log { get; set; }
public bool status { get; set; }
public string title { get; set; }
public DateTime created { get; set; }
public DateTime changed { get; set; }
public bool promote { get; set; }
public bool sticky { get; set; }
public bool default_langcode { get; set; }
public bool revision_translation_affected { get; set; }
public string moderation_state { get; set; }
public Path path { get; set; }
public string field_equipment_name { get; set; }
}
public class Data
{
public string type { get; set; }
public string id { get; set; }
public Meta meta { get; set; }
public Links links { get; set; }
public Attributes attributes { get; set; }
public Relationships relationships { get; set; }
}
public class FieldEquipmentArea
{
public object data { get; set; }
public Links links { get; set; }
}
public class Jsonapi
{
public string version { get; set; }
public Meta meta { get; set; }
}
public class Links
{
public Self self { get; set; }
public Related related { get; set; }
public Next next { get; set; }
}
public class Meta
{
public Links links { get; set; }
public string drupal_internal__target_id { get; set; }
}
public class Next
{
public string href { get; set; }
}
public class NodeType
{
public Data data { get; set; }
public Links links { get; set; }
}
public class Path
{
public string alias { get; set; }
public int pid { get; set; }
public string langcode { get; set; }
}
public class Related
{
public string href { get; set; }
}
public class Relationships
{
public NodeType node_type { get; set; }
public RevisionUid revision_uid { get; set; }
public FieldEquipmentArea field_equipment_area { get; set; }
}
public class RevisionUid
{
public Data data { get; set; }
public Links links { get; set; }
}
public class Self
{
public string href { get; set; }
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论