1

This is an odd case, but it's a pattern we use a lot to deal with SQL back ends when we don't want to break the data into a separate table.

The problem here is, on deserialization, MyList has two items in it, instead of one. The root of the problem is that when the deserializer gets to the MyList property it reuses the existing value instead of resetting the property.

Here is the code:

public class Jason
{
    public object FromJSON(string json, Type t)
    {
        JsonSerializerSettings s = new JsonSerializerSettings();
        s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        s.NullValueHandling = NullValueHandling.Ignore;
        return Newtonsoft.Json.JsonConvert.DeserializeObject(json, t, s);
    }

    public string ToJSON(object o)
    {
        JsonSerializerSettings s = new JsonSerializerSettings();
        s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        s.NullValueHandling = NullValueHandling.Ignore;
        return Newtonsoft.Json.JsonConvert.SerializeObject(o, s);
    }

    public string MyListString
    {
        get { return ToJSON(_MyList); }
        set { _MyList = (List<string>)FromJSON(value, typeof(List<string>)); }
    }

    private List<string> _MyList = new List<string>();
    public List<string> MyList
    {
        get { return _MyList; }
        set { _MyList = value; }
    }

}

[TestFixture]
public class JasonTests : TestFixtureBase
{
    [Test]
    public void Jason()
    {
        Jason j = new Jason();
        j.MyList.Add("hello");

        string json = j.ToJSON(j);

        Jason j2 = (Jason)j.FromJSON(json, typeof(Jason));

        Assert.AreEqual(j.MyList.Count, j2.MyList.Count);
    }
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Jason Wall
  • 571
  • 1
  • 6
  • 15
  • possible duplicate of [Property getter invoked during deserialization instead of setter](http://stackoverflow.com/questions/25553459/property-getter-invoked-during-deserialization-instead-of-setter) – Brian Rogers Sep 11 '14 at 01:54

1 Answers1

1

Ok, after examining the source code and trying to fix what I thought was a bug, then googling around to see if anyone else had this problem it occurred to me that there might be a setting, and sure enough, there was. Here is the fixed code:

public class Jason
{
    public object FromJSON(string json, Type t)
    {
        JsonSerializerSettings s = new JsonSerializerSettings();
        s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        s.NullValueHandling = NullValueHandling.Ignore;
        s.ObjectCreationHandling = ObjectCreationHandling.Replace; // without this, you end up with duplicates.
        return Newtonsoft.Json.JsonConvert.DeserializeObject(json, t, s);
    }

    public string ToJSON(object o)
    {
        JsonSerializerSettings s = new JsonSerializerSettings();
        s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        s.NullValueHandling = NullValueHandling.Ignore;
        s.ObjectCreationHandling = ObjectCreationHandling.Replace; // without this, you end up with duplicates.
        return Newtonsoft.Json.JsonConvert.SerializeObject(o, s);
    }

    public string MyListString
    {
        get { return ToJSON(_MyList); }
        set { _MyList = (List<string>)FromJSON(value, typeof(List<string>)); }
    }

    private List<string> _MyList = new List<string>();
    public List<string> MyList
    {
        get { return _MyList; }
        set { _MyList = value; }
    }
}

[TestFixture]
public class JasonTests : TestFixtureBase
{

    [Test]
    public void Jason()
    {
        Jason j = new Jason();
        j.MyList.Add("hello");

        string json = j.ToJSON(j);

        Jason j2 = (Jason)j.FromJSON(json, typeof(Jason));

        Assert.AreEqual(j.MyList.Count, j2.MyList.Count);

    }
 }
lantrix
  • 441
  • 9
  • 17
Jason Wall
  • 571
  • 1
  • 6
  • 15