runtime icon indicating copy to clipboard operation
runtime copied to clipboard

strange Constructor behavior under last version

Open vsfeedback opened this issue 3 years ago • 6 comments

This issue has been moved from a ticket on Developer Community.


[severity:It's more difficult to complete my work] [regression] [worked-in:17.3.0 preview 2] String json = someTextData ProgramSettings? tmpProgramSettings = new ProgramSettings(someText_Required);

The following line is trigerring the ProgramSettings Constructor tmpProgramSettings = JsonConvert.DeserializeObject(json);

but it's calling the constructor with an EMPTY required parameter Wich is not only odd but also crash my program.

To avoid it, I have to Create a parameterless constructor.


Original Comments

Tracy Wang [MSFT] on 7/10/2022, 08:18 PM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:14 AM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:48 AM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:59 AM:

(private comment, text removed)

Feedback Bot on 7/11/2022, 05:30 PM:

(private comment, text removed)

Cassie Li [MSFT] on 7/11/2022, 07:15 PM:

(private comment, text removed)

Feedback Bot on 7/11/2022, 07:54 PM:

(private comment, text removed)


Original Solutions

(no solutions)

vsfeedback avatar Aug 03 '22 19:08 vsfeedback

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.

Issue Details

This issue has been moved from a ticket on Developer Community.


[severity:It's more difficult to complete my work] [regression] [worked-in:17.3.0 preview 2] String json = someTextData ProgramSettings? tmpProgramSettings = new ProgramSettings(someText_Required);

The following line is trigerring the ProgramSettings Constructor tmpProgramSettings = JsonConvert.DeserializeObject(json);

but it's calling the constructor with an EMPTY required parameter Wich is not only odd but also crash my program.

To avoid it, I have to Create a parameterless constructor.


Original Comments

Tracy Wang [MSFT] on 7/10/2022, 08:18 PM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:14 AM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:48 AM:

(private comment, text removed)

Patrice Charbonneau on 7/11/2022, 06:59 AM:

(private comment, text removed)

Feedback Bot on 7/11/2022, 05:30 PM:

(private comment, text removed)

Cassie Li [MSFT] on 7/11/2022, 07:15 PM:

(private comment, text removed)

Feedback Bot on 7/11/2022, 07:54 PM:

(private comment, text removed)


Original Solutions

(no solutions)

Author: vsfeedback
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

msftbot[bot] avatar Aug 03 '22 19:08 msftbot[bot]

Would it be possible to share a minimal reproduction as well a stacktrace of the error you are experiencing? It looks like you are using Json.NET, I would recommend opening an issue in that project.

eiriktsarpalis avatar Aug 03 '22 19:08 eiriktsarpalis

This issue has been marked needs-author-action and may be missing some important information.

msftbot[bot] avatar Aug 03 '22 19:08 msftbot[bot]

Hi,

I have submitted to Microsoft full demo project to reproduce it. let me find it back I'll post it here

ghost avatar Aug 07 '22 09:08 ghost

Here the demo example, I got rid of Newtonsoft to show it's a .NET bug and not NewtonSoft https://lebudget.com/download/BugConstructor2022-07-11.zip

ghost avatar Aug 07 '22 09:08 ghost

I've extracted the following minimal reproduction from the code sample:

using System;
using System.Collections.Generic;
using System.Text.Json;

string json = "{  \"dicSettings\": {  }}";

//put a break point here and Debug Follow next line
//The Next line Called the ProgramSettings constructor with no parameter.  This is NOT supposed to happen
//JsonConvert.DeserializeObject<ProgramSettings>(json);
JsonSerializer.Deserialize<ProgramSettings>(json);

public class ProgramSettings
{
    public Dictionary<String, String> dicSettings = new Dictionary<String, String>();

    //public ProgramSettings()
    //{
    //    //If you uncomment this, it fix it, but it make no sense that the constructor is called
    //}

    public ProgramSettings(String pstrNewValue)
    {
        dicSettings.Add(pstrNewValue, "Ok");
    }
}

The code fails with the following exception:

System.InvalidOperationException: Each parameter in the deserialization constructor on type 'ProgramSettings' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. Fields are only considered when 'JsonSerializerOptions.IncludeFields' is enabled. The match can be case-insensitive.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ConstructorParameterIncompleteBinding(Type parentType)
   at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)

However, this is by-design behavior. The serializer (either Json.NET or System.Text.Json) must bind to a constructor in order to be able to deserialize the type. See this article for more details on constructors are used in the context of deserialization.

eiriktsarpalis avatar Sep 02 '22 13:09 eiriktsarpalis