contentful / contentful.net

.NET Library for Contentful's Content Delivery and Management API
MIT License
95 stars 52 forks source link

JsonSerializationException when retrieving entry with rich text field #340

Closed blairlundin closed 3 weeks ago

blairlundin commented 1 month ago

I am getting a JsonSerializationException when trying to retrieve entries that contain a Rich Text field using the ContentfulManagementClient:

Message: 
Newtonsoft.Json.JsonSerializationException : Could not create an instance of type Contentful.Core.Models.IContent. Type is an interface or abstract class and cannot be instantiated. Path 'text.content[0].nodeType', line 1, position 980.

  Stack Trace: 
JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
JsonSerializer.Deserialize(JsonReader reader, Type objectType)
JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
JToken.ToObject(Type objectType)
JToken.ToObject[T]()
<>c__DisplayClass22_0`1.<GetEntriesForLocale>b__0(JObject j) line 428
SelectListIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
SelectListIterator`2.ToList()
ContentfulManagementClient.GetEntriesForLocale[T](QueryBuilder`1 queryBuilder, String locale, String spaceId, CancellationToken cancellationToken) line 428

This is the model I am trying to deserialize to:

public class IconText
{
    public string InternalName { get; set; } = string.Empty;
    public string Title { get; set; } = string.Empty;
    public Document Text { get; set; } = new();
}

And this is how I am trying to get the entries:

var client = new ContentfulManagementClient(httpClient, contentfulOptions);
var queryBuilder = new QueryBuilder<IconText>()
    .ContentTypeIs("iconText");
var entries = await client.GetEntriesForLocale(queryBuilder, "en");

I did some debugging and found the URL that is being called by the client: https://api.contentful.com/spaces/<spaceid>/environments/<environment>/entries?content_type=iconText

And this is what the API returns (I removed the contents of sys for brevity)

{
    "sys": {
        "type": "Array"
    },
    "total": 1,
    "skip": 0,
    "limit": 100,
    "items": [
        {
            "metadata": {
                "tags": [],
                "concepts": []
            },
            "sys": {
            },
            "fields": {
                "internalName": {
                    "en": "Test Icon Text"
                },
                "title": {
                    "en": "Test Title"
                },
                "text": {
                    "en": {
                        "nodeType": "document",
                        "data": {},
                        "content": [
                            {
                                "nodeType": "paragraph",
                                "data": {},
                                "content": [
                                    {
                                        "nodeType": "text",
                                        "value": "Text",
                                        "marks": [],
                                        "data": {}
                                    }
                                ]
                            }
                        ]
                    }
                }
            }
        }
    ]
}
Roblinde commented 1 month ago

Hi @blairlundin

That sounds peculiar, I'll have a look when I get some time.

Roblinde commented 3 weeks ago

@blairlundin I believe this should now be resolved in version 8.0.0