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

JsonConstrutor different behavior between Newtonsoft.Json and System.Text.Json #46480

Closed
NN--- opened this issue Dec 31, 2020 · 3 comments
Closed

Comments

@NN---
Copy link
Contributor

NN--- commented Dec 31, 2020

Description

    public class Q
    {
        [JsonConstructor]
        public Q(int? x)
        {
            if (x is null) throw new Exception();
            X = x.Value;
        }
        
        public int X { get; }
    }

Given string:

var str = JsonSerializer.Deserialize<Q>("{\"X\":123}" ");

It is deserialized fine with Newtonsoft, but not with System.Text.
The reason is that constructor parameter type is int? while the property has type of int.
Newtonsoft doesn't validate it, giving an option to do anything in the constructor.

There are possible workarounds but they are not as simple as the original code:

Make property private and add a public non nullable:

    public class Q
    {
        [JsonConstructor]
        public Q(int? x)
        {
            if (x is null) throw new Exception();
            X = x.Value;
        }

        public int? X { get; }

        [JsonIgnore]
        public int NonNullableX => X!.Value;
    }

Annotate nullable as non nullable, however it requires explicit call to Value.:

    public class Q
    {
        [JsonConstructor]
        public Q(int? x)
        {
            if (x is null) throw new Exception();
            X = x.Value;
        }

        [DisallowNull][NotNull]
        public int? X { get; }
    }

Configuration

Regression?

Not a regression.

Other information

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Dec 31, 2020
@Clockwork-Muse
Copy link
Contributor

Um, if you throw an exception like that, why not just make the constructor take a non-nullable?

@NN---
Copy link
Contributor Author

NN--- commented Dec 31, 2020

It is a general question.
The argument validation can be more complicated than this.

@layomia
Copy link
Contributor

layomia commented Jan 25, 2021

Dup of #44428.

@layomia layomia closed this as completed Jan 25, 2021
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Jan 25, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Feb 24, 2021
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

4 participants