Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throws an exception on a simple JSON structure return. #30938

Closed
DonaldAirey opened this issue Sep 24, 2019 · 13 comments
Closed

Throws an exception on a simple JSON structure return. #30938

DonaldAirey opened this issue Sep 24, 2019 · 13 comments

Comments

@DonaldAirey
Copy link

I don't have time to figure out exactly what's buggy about the System.Text.JSON, but this code was working in .NET Core 2.2.

            return this.Ok(
                new
                {
                    deletedEntityTrees,
                    entities,
                    entityTrees,
                    users,
                });

Now I get:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLQ11IPL386G", Request id "0HLQ11IPL386G:00000001": An unhandled exception was thrown by the application.
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

When I switch back to NewtonSoft, it works just like it did before the upgrade to .NET Core 3.0.

@scalablecory
Copy link
Contributor

JsonSerializer in .NET Core 3.0 does not support circular references. A proposal to support this is being worked on in #30820.

If you believe this is not a cycle and instead you just have a very deep heirarchy, you can set JsonSerializerOptions.MaxDepth to something larger than the default.

@ahsonkhan
Copy link
Member

@gammafour - can you share what your object graph looks like that you are trying to serialize? Do you have cycles in your object or is it that your graph actually really deep that you are going over the 1_000 max depth?

When I switch back to NewtonSoft, it works just like it did before the upgrade to .NET Core 3.0.

What settings/options do you use with Newtonsoft for it to work?

@timmyreilly
Copy link

timmyreilly commented Nov 7, 2019

I ran into a similar issue when deserializing a model with a one to many relationship for a Blazor based web app. To solve the issue we had to add JsonIgnore and a reference to System.Text.Json 4.7.0-preview2.19523.17

...
using System.Text.Json.Serialization;

public class ThingStatus : BaseEntity
    {
        public string Status { get; set; }

        [JsonIgnore] // 
        public List<Thing> Things { get; set; }
    }
 public class Thing: BaseEntity
    {
        public string Name { get; set; }

        public string Description { get; set; }

        public DateTime DueDate { get; set; }

        public ThingStatus ThingStatus { get; set; }

        public int ThingStatusId { get; set; }
    }

@JAYARAJ2014
Copy link

@timmyreilly Thanks for your suggestion. I had the same problem and JsonIgnore attribute worked for me. I could not find JSonSerializationOptions for reference loop handling in Core 3.0

@ahsonkhan
Copy link
Member

@JAYARAJ2014 - the reference loop feature is WIP for 5.0, see: https://github.com/dotnet/corefx/issues/41002

@Alexei000
Copy link

Another workaround is to use Microsoft.AspNetCore.Mvc.NewtonsoftJson as NewtonsoftJson is more mature than System.Text.JSON. Example:

services.AddControllersWithViews(opt =>
{
    ....
}
.AddNewtonsoftJson();
// optionally tackle cycles through (opt => opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

@jozkee
Copy link
Member

jozkee commented Jan 21, 2020

The preview version for ReferenceHandling feature is here.

var options = new JsonSerializerOptions
{
    ReferenceHandling = ReferenceHandling.Preserve
};

string json = JsonSerializer.Serialize(objectWithLoops, options);

Here's the spec doc including samples and notes about many scenarios.
If you want to add feedback, feel free to leave a comment in https://github.com/dotnet/corefx/issues/41002.

@catfood
Copy link

catfood commented Jan 22, 2020

@jozkee, I tried using the alpha from the dotnet5 gallery and it seems to be a prior build number (19523.8) that doesn't yet have the ReferenceHandling property. Do you know what I'm doing wrong?

PS C:\Users\mark\.nuget\packages\system.text.json\5.0.0-alpha1.19523.8\lib\netcoreapp3.0> [System.Reflection.Assembly]::LoadFrom(".\System.Text.Json.dll")
[System.Reflection.Assembly]::LoadFrom(".\System.Text.Json.dll")

GAC    Version        Location
---    -------        --------
False  v4.0.30319     C:\Users\mark\.nuget\packages\system.text.json\5.0.0-alpha1.19523.8\lib\netcoreapp3.0\System.T...

@jozkee
Copy link
Member

jozkee commented Jan 22, 2020

@catfood make sure to select version 5.0.0-alpha.1.20071.1 from the dropdown.

image

@GrangeLife
Copy link

@jozkee the highest version for System.Text.Json that I am seeing is only 4.7.0. I have the Include Prerelease checked.

@jozkee
Copy link
Member

jozkee commented Jan 27, 2020

@GrangeLife You are probably using default package source gallery (nuget.org).

Go to Package Manager Settings and add dotnet5 daily feed to your Package Sources and search there for version 5.0.0-alpha.1.20071.1.

https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json

@kruppjunker
Copy link

Hello,
i have installed the alpha versions, after editing my source gallery.
Packages

The ReferenceHandling wont show up in my JsonOptions. I added Jsonoptions for my Controllers.
services.AddControllers().AddJsonOptions(option => { option.JsonSerializerOptions.PropertyNamingPolicy = null; option.JsonSerializerOptions.MaxDepth = 256; });

@jozkee
Copy link
Member

jozkee commented Jan 28, 2020

@erkanKR, it seems that you are using a wrong version. Make sure to select 5.0.0-alpha.1.20071.1. Let me know if it still does not show up.

@ahsonkhan
Copy link
Member

i have installed the alpha versions, after editing my source gallery.

The versioning schema of the packages on the nightly feed changed a bit. Since we went from alpha1.<version> to alpha.1.<version>, the newest packages don't show up on the top as they are sorted alphabetically (note the extra .). As @jozkee mentioned, please look at the publish date and make sure to grab 5.0.0-alpha.1.20071.1 or higher to get the feature.

cc @mmitche, @safern

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 5.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests