aspnetcore: JsonSerializerOptions constructor is not copying the context

since the JsonSerializerOptions doesn’t copy the _context from the old to the new, the json source generator stuff will not work with mvc output formatter. the call that wants to make a copy is below. since Encoder is null, it tries to make a new JsonSerialzierOptions and this constructor ignores _context.

 internal static SystemTextJsonOutputFormatter CreateFormatter(JsonOptions jsonOptions)
        {
            var jsonSerializerOptions = jsonOptions.JsonSerializerOptions;

            if (jsonSerializerOptions.Encoder is null)
            {
                // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
                jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions)
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                };
            }

            return new SystemTextJsonOutputFormatter(jsonSerializerOptions);
        }

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Bringing this back up - the only reason we use the copy constructor is to use the relaxed encoding which produces terser JSON for non-ASCII characters. Newtonsoft.Json uses a relaxed encoding by default and we’d wanted to keep parity with it when we started off. But given minimal endpoints do not do this, perhaps we can consider changing this behavior for 7.0 and not use the relaxed encoding with MVC.

Note that we’d continue having to use the copy-constructor with the STJ-based IJsonHelper - https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.ViewFeatures/src/Rendering/SystemTextJsonHelper.cs#L36-L39, but that gets a lot less use. Perhaps it might suffice to provide a warning there if we know a JsonSerializerContext is associated with the JsonSerializerOptions.

It might also be worthwhile consider patching this in 6.0 where we do not call the copy constructor if an AppContext switch is present. The current behavior is really buggy and silently limits the usage of the source generator in MVC apps.