-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
JsonSerializer support for immutable classes and structs. #29895
Comments
JsonSerializer
support for immutable class
es and struct
s.
This is a known limitation of the |
You can write a custom converter for this. |
I totally was going to write an issue about this, glad I noticed this before that 🙃 I personally thought that writing a private setter on otherwise a readonly property purely because of JSON (de)serialization is kind of hacky. I know that I could write a custom converter (when it's implemented) or use a constructor (which I remember will be supported soon? I could be wrong) but... that's effort |
For the 3.0 release, there is no planned additional support for calling a non-default constructor during deserialization. That would have to be done by a custom converter. |
That's fine, as long as it's in the plan in some way... One step at a time 😁 |
There's a fair bit of overlap with this issue and https://github.com/dotnet/corefx/issues/38569. |
@khellang, it probably overlaps because this issue is dotnet/corefx#38569 😄 I guess you meant 41973? |
LOL, no, I meant https://github.com/dotnet/corefx/issues/40399 😂 |
@ahsonkhan Is there work currently being done on this issue? If not, is this something where a pull request would be considered? |
seems would support Deserialize anonymous object? |
From @endeffects in dotnet/corefx#40399:
|
From @EdiWang in https://github.com/dotnet/corefx/issues/41102:
|
I have started to implement a custom converter for The converter is able to read "basic" types. The type must have exactly one constructor with at least one parameter. The type has not be sealed. Example public sealed class ProgramSettings
{
public ProgramSettings(Uri baseUrl, string adminName, string adminPassword)
{
BaseUrl = baseUrl;
AdminName = adminName;
AdminPassword = adminPassword;
}
public Uri BaseUrl { get; }
public string AdminName { get; }
public string AdminPassword { get; }
}
public void DeserializeSettings()
{
const string settingsJson = @"{""BaseUrl"": ""https://example.com:8999"", ""AdminName"": ""admin"", ""AdminPassword"": ""topsecret""}";
var options = new JsonSerializerOptions();
options.Converters.Add(new ImmutableConverter());
var programSettings = JsonSerializer.Deserialize<ProgramSettings>(settingsJson, options);
var baseUrl = programSettings.BaseUrl; // https://example.com:8999
var adminName = programSettings.AdminName; // admin
var adminPassword = programSettings.AdminPassword; // topsecret
} I have uploaded a nuget package Obviously.System.Text.Json, it is not yet indexed. Feedback and PRs are always welcome 😉 |
From @ahedreville in #1925:
|
System.Text,Json needs a parameterless default constructor: dotnet/runtime#29895 (comment)
…tion working. Upgrading to .NET 5.0 should fix this as it supports working with classes without default constructors dotnet/runtime#29895
* Start on persistence * More work on deserializing events * Add some custom converters as a hack to get serialization/deserialization working. Upgrading to .NET 5.0 should fix this as it supports working with classes without default constructors dotnet/runtime#29895 * Upgrade test assemblies to .NET 5.0 to take advantage of serialization fixes that allow JSON to be deserialized into classes without default constructors * Add a custom attribute that the library uses to determine event names in the first instance and centralise the logic for mapping event names to types and vice versa * Simplify repository by pulling all the logic to get event names into the serializer * Add some tests for EventNameMapping * Allow proper serialization of exceptions * Test to ensure that building the event routes also wires up the event name mappings * Simplify EventNameMap name and ensure it's consistent everywhere
A common pattern is to make data objects immutable for many different reasons.
For example
Point
:It would be very helpful if
JsonSerializer
supported immutableclass
es/struct
s like that, especially since Newtonsoft Json.NET supports deserialization through the constructor.However there are a few issues surrounding immutable types:
Constructor parameter names are usually
camelCase
while Properties arePascalCase
. One way to solve this is by settingJsonSerializerOptions.PropertyNameCaseInsensitive
in totrue
. Another way is to use theDeconstruct
-pattern introduced in C# 7.0, instead of Properties for serialization.There may be several constructors (and
Deconstruct
methods). So it's not always clear which to use. Newtonsoft Json.NET uses a JsonConstructorAttribute.htm, which has the disadvantage that the data objects need to know about serialization.Constructor parameters, properties and
Deconstruct
method parameters might not match up, possibly leading to confusing situations where deserializing a previously serialized object does not work.Immutable structs always still have a default parameterless constructor.
The text was updated successfully, but these errors were encountered: