dotnet / dotnet/aspnetcore

NewtonsoftJsonHubProtocol does not seem to respect setting for MaxDepth

Open
#51,254 5 comments 1 reaction 0 assignees View on GitHub
area-signalr External
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

I have a signalR application that sends complex objects between client and server, and I recently reached a case where the default MaxDepth of json deserialization is not sufficient.

My application is failing with:
```
Client disconnected. Connection Id:55dM9bnlnmLLNvlvgw05Tw. Exception: System.IO.InvalidDataException: Error reading JSON.
---> Newtonsoft.Json.JsonReaderException: The reader's MaxDepth of 64 has been exceeded. Path 'arguments[0].args.segment.children[9].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[7].children[0]', line 1, position 10348.
at Newtonsoft.Json.JsonReader.Push(JsonContainerType value)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.Linq.JContainer.ReadContentFrom(JsonReader r, JsonLoadSettings settings)
at Newtonsoft.Json.Linq.JContainer.ReadTokenFrom(JsonReader reader, JsonLoadSettings options)
at Newtonsoft.Json.Linq.JArray.Load(JsonReader reader, JsonLoadSettings settings)
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.TryParseMessage(ReadOnlySequence`1& input, IInvocationBinder binder, HubMessage& message)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.DispatchMessagesAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
```
That is all fine, until I tried to set the value to a higher value, and was unsuccessful in doing so, and the error still complains about the max depth of 64.

I tried the following:
1. Using the "AddNewtonsoftJsonProtocol" extension method from Microsoft.Extensions.DependencyInjection.NewtonsoftJsonProtocolDependencyInjectionExtensions and setting options.PayloadSerializerSettings.MaxDepth to a higher value - this is not respected
2. Implementing IConfigureOptions in a custom class and setting options.PayloadSerializerSettings.MaxDepth to a higher value from inside the void Configure(NewtonsoftJsonHubProtocolOptions) method. Of course, also did the .ConfigureOptions on the IServiceCollection in ConfigureServices method of my Startup.cs
3. I also got desperate and tried to do ` JsonConvert.DefaultSettings = () => new JsonSerializerSettings { MaxDepth = 256 };` to use directly newtonsoft in the hope that it will respect the global default settings factory. Still no luck.

All my attempts ended up with the exact same error, complaining about the max depth of 64 being reached, and this causes my signalR connection to drop.

Please help with either providing the proper way to override that configuration, or help with a workaround (for example, is there a way to prevent signalR from deserializing my parameter, obtain somehow the raw content, and let my code handle the deserialization explicitly, in which case I can control the deserialization settings inline?

Looking at the code, in the NewtonsoftJsonHubProtocol method ParseMessage, when doing the JArray.Load it does indeed seem like the PayloadSerializer member is not used. Please evaluate if this is right. (there might be other places, not just JArray handling, but this is the one that is a match for my scenario, according to the stack trace too)

Thank you!

### Expected Behavior

I expect to be able to change the value of MaxDepth used by the deserializer when handling the signalR messages so that I am not stuck with the default depth of 64 on the Newtonsoft Json protocol.

### Steps To Reproduce
Set up a project with SignalR and NewtonsoftJsonProtocol.
Send a message from the client to the server with an object that has more than 64 levels of nesting. - expected to have it fail and disconnect.
Now try to change the MaxDepth configuration on the protocol - it will still fail with the same error - that the MaxDepth of 64 was reached

### Exceptions (if any)
```
Client disconnected. Connection Id:55dM9bnlnmLLNvlvgw05Tw. Exception: System.IO.InvalidDataException: Error reading JSON.
---> Newtonsoft.Json.JsonReaderException: The reader's MaxDepth of 64 has been exceeded. Path 'arguments[0].args.segment.children[9].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[7].children[0]', line 1, position 10348.
at Newtonsoft.Json.JsonReader.Push(JsonContainerType value)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.Linq.JContainer.ReadContentFrom(JsonReader r, JsonLoadSettings settings)
at Newtonsoft.Json.Linq.JContainer.ReadTokenFrom(JsonReader reader, JsonLoadSettings options)
at Newtonsoft.Json.Linq.JArray.Load(JsonReader reader, JsonLoadSettings settings)
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
at Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.TryParseMessage(ReadOnlySequence`1& input, IInvocationBinder binder, HubMessage& message)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.DispatchMessagesAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
```
### .NET Version

7.0.401

### Anything else?

_No response_

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.