Skip to content

Breaking change: non-public parameterless ctors will not be used for deserialization with JsonSerializer #20887

@layomia

Description

@layomia

By default, non-public parameterless ctors will not be used for deserialization with JsonSerializer, to be consistent across all supported TFMs

Version introduced

.NET 5.0 preview 1

Old behavior

  • On .NET Core 3.0+, we allow internal/private ctors of POCOs and call them while deserializing.
  • On netstandard2.0/2.1, we don’t and throw a MissingMethodException: No parameterless constructor defined for this object. (from Activator.CreateInstance).

New behavior

Non-public constructors are ignored by the serializer by default. This includes parameterless constructors. The serializer will use one of the following constructors for deserialization.

  • Public constructor annotated with JsonConstructorAttribute.
  • Public parameterless constructor.
  • Public parameterized constructor (if it is the only public constructor present)

If none of the above are present, a NotSupportedException will be thrown if deserialization of the type is attempted.

Reason for change

  • Enforce consistent behavior between all TFMs that System.Text.Json builds for (.NET Core 3.0+, .netstandard 2.0+)
  • JsonSerializer shouldn't be calling non-public surface area of types by default (whether that's ctor, properties, or fields).

Recommended action

  • If the user controls the own type and it is feasible, make the parameterless constructor public
  • Implement a JsonConverter<T> for the type and control the deserialization behavior

Category

  • ASP.NET Core
  • C#
  • Code analysis
  • Core .NET libraries
  • Cryptography
  • Data
  • Debugger
  • Deployment
  • Globalization
  • Interop
  • JIT
  • LINQ
  • Managed Extensibility Framework (MEF)
  • MSBuild
  • Networking
  • Printing
  • Security
  • Serialization
  • Visual Basic
  • Windows Forms
  • Windows Presentation Foundation (WPF)
  • XML, XSLT

Affected APIs

JsonSerializer.Deserialize
JsonSerializer.DeserializeAsync


Issue metadata

  • Issue type: breaking-change

Metadata

Metadata

Assignees

Labels

🏁 Release: .NET 5Work items for the .NET 5 releasebreaking-changeIndicates a .NET Core breaking change

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions