JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.71k stars 3.24k forks source link

String Property With Math Function Not Deserialized Correctly #2917

Closed GABowers closed 9 months ago

GABowers commented 9 months ago

I have a simple class that I use to do mathematical calculations. There's a string property that contains the initial formula. Unfortunately it does not get deserialized correctly in Json - the serialized string DOES contain the property but it disappears when deserializing.

Source/destination types

    public class AgentProperty
    {
        public string Name { get; }
        public double InitialValue { get; }
        public string Formula { get; }

        public AgentProperty(string name, double v, string form)
        {
            Name = name;
            InitialValue = v;
            Formula = form;
        }

        public string ToJson()
        {
            return JsonConvert.SerializeObject(this);
        }

        public static AgentProperty FromJson(string json)
        {
            var deserialized = JsonConvert.DeserializeObject<AgentProperty>(json);
            return deserialized;
        }
    }

Source/destination JSON

{"Name":"Property","InitialValue":0.0,"Formula":"f(x)=x+1"}

Expected behavior

The deserialized object should have the same property values of the original object.

Actual behavior

The "Formula" string is parsed as a null in the Json deserializer (visible in the constructor of the class when attempting to deserialize).

Steps to reproduce

    static AgentProperty AP
    {
        get
        {
            string formula = "f(x)=x+1";
            return new AgentProperty("Property", 0, formula);
        }
    }
    [TestMethod()]
    public void FromJsonTest()
    {
        var s = AP.ToJson();
        var ap = AgentProperty.FromJson(s);
        Assert.IsTrue(ap.Name.Equals("Property"));
        Assert.IsTrue(ap.InitialValue.Equals(0));
        Assert.IsTrue(ap.Formula.Equals("f(x)=x+1"));
    }
GABowers commented 9 months ago

I just realized my mistake: My input variables to the class constructor need to be the same name as the properties. The following constructor allows things to pass:

public AgentProperty(string name, double initialValue, string formula)
{
    Name = name;
    InitialValue = initialValue;
    Formula = formula;
}