dotnet / dotnet/aspnetcore

Deserialization issue in Microsoft.AspNetCore.Mvc.NewtonsoftJson

Open
#18,780 6 comments 0 reactions 0 assignees View on GitHub
affected-very-few area-mvc enhancement feature-model-binding severity-nice-to-have
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Describe the bug
When i was using Microsoft.AspNetCore.Mvc.NewtonsoftJson in my app i switched to newtonsoft json instead of using System.Text.Json which is coming by default. However i had a test which were testing rest api with various validational cases. One of the cases was when we use wrong json which can’t be properly deserialized to an appropriate DTO and be passed to a controller POST method as a request body.
This json properly result in invalid model state behaviour - however the internal error handling shows weird error messages to me stating that i have problems in array items by non-existing indexes. I debugged the problem a bit but the only thing i get is that the problem is somewhere inside JsonSerializerInternalReader.Deserialize method which catches the error for me which i posted down bellow. In this exception we can see a path recoveryGroups[2] - which is not existing cause i have only 1 recovery group in my json array. It works correctly if i’m using System.Text.Json by default. It works as expected also if i try to deserialize with Newtonsoft.Json version 12 like this:
JsonConvert.DeserializeObject(json);

### To Reproduce
In order to reproduce this issue you need to a simple rest api with post method and use json like this as a request body(lmk if you need a dto class structure also which this json deserializes to):
`
{
"name": "runBookName1",
"platformType": 0,
"timeCreated": "2019-09-09T11:36:38.236Z",
"timeUpdated": "2019-09-09T11:36:38.236Z",
"updatedByUserName": "string ByUserName",
"recoveryGroups": [
{
"identifier": "string identifier",
"name": [],
"description": "string name",
"vms": [
{
"identifier": "string vms identifier",
"name": "string vms name",
"vmPath": "string VmPath",
"powerOn": true,
"vcenter": "string VmsVcenter",
"storage": "string VmsStorage",
"vmxLun": "string vmxLun",
"resourcePool": "string resourcePool",
"diskMap": {
"additionalProp1": {
"datastoreId": "string DiskMapDatastoreId",
"copy": "string copy",
"vmotion": "string vmotion"
},
"additionalProp2": {
"datastoreId": "string DiskMapDatastoreId",
"copy": "string copy",
"vmotion": "string vmotion"
},
"additionalProp3": {
"datastoreId": "string DiskMapDatastoreId",
"copy": "string copy",
"vmotion": "string vmotion"
}
},
"networkMap": {
"additionalProp1": "string additionalProp1",
"additionalProp2": "string additionalProp2",
"additionalProp3": "string additionalProp23"
},
"recoveryStatus": 0
}
],
"timeStarted": "2019-09-09T11:36:38.236Z",
"timeCompleted": "2019-09-09T11:36:38.236Z"
}
]
}
`
Inside this json i used
"name": [],
however name is a string field in my dto object i’m trying to deserialize to.
This is my validational case to return invalid model state in case of invalid json. As a result i also see
"Infinite loop detected from error handling" inside inner exceptions which should not be the case. The result should be a different exception like wrong symbol detected for path recoveryGroups[0].name and that’s it.

`
Newtonsoft.Json.JsonSerializationException: Error converting value "description" to type ‘Faction.Hdraas.RestApi.v1.Controllers.Dto.RunbookDto’. Path ‘recoveryGroups[2]’, line 11, position 19.
---> System.ArgumentException: Could not cast or convert from System.String to Faction.Hdraas.RestApi.v1.Controllers.Dto.RunbookDto.
at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
`

### Further technical details
- ASP.NET Core version 3.1.1
- output of `dotnet --info`:
.NET Core SDK (reflecting any global.json):
Version: 3.1.101
Commit: b377529961

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.13
OS Platform: Darwin
RID: osx.10.13-x64
Base Path: /usr/local/share/dotnet/sdk/3.1.101/

Host (useful for support):
Version: 3.1.1
Commit: a1388f194c

.NET Core SDKs installed:
2.1.502 [/usr/local/share/dotnet/sdk]
2.2.103 [/usr/local/share/dotnet/sdk]
2.2.402 [/usr/local/share/dotnet/sdk]
3.0.101 [/usr/local/share/dotnet/sdk]
3.1.100 [/usr/local/share/dotnet/sdk]
3.1.101 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
- IDE is JetBrains Rider 2019.3.1

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.