开发者

Deserializing Protected constructed object from json

I'm using newton's json.net serializer. When deserializing the json to 'TheFox'; it enters to the protected ctor and gets the default property values. But not the property values in the json string. Can i solve this problem without using dto or any other mapper framework?

class TheFox
    {

    string _Id;
    string _Name;

    protected TheFox()
    {
        _Id = "Default Id";
        _Name = "Default Name";
    }

    public TheFox(string id, string name) : this()
    {
        _Name = name;
        _Id = id;
    }

    public string Id
    {
        get { return _Id; }
    }

    public string Name
    {
        get { return _Name; }
    }
}

That's the test:

        var fox = new TheFox("FoxId", "FoxTail");
        var json = JsonConvert.SerializeObject(fox);
        Console.WriteLine(json);

        var settings = new JsonSerializerSettings ()
        {
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstruct开发者_JS百科or
        };

        var returned = JsonConvert.DeserializeObject<TheFox> (json, settings);

        Assert.IsTrue (returned.Id != "Default Id");
        Assert.IsTrue (returned.Name != "Default Name");


Checked the source of in json.net and there's no way for now. Because if the given property is readonly it skips the setting the value stage. may be needs an internal field populator feature.

private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
    {
      // bla.. bla.. bla..
      if (!property.Writable && !useExistingValue)
      {
        reader.Skip();
        return;
      }

That method is a bad one, it needs an instantiated object to fill but it works.

var a = new TheFox("x", "y");
var json = JsonConvert.SerializeObject(a);
Console.WriteLine(json);

var returned = JsonConvert.DeserializeAnonymousType(json, new TheFox("q", "a")); 

Assert.That(a.Id, Is.EqualTo(returned.Id));
Assert.That(a.Name, Is.EqualTo(returned.Name));


    class TheFox
    {
      string _Id;
      string _Name;

      protected TheFox() : this("Default Id", "Default Name")

      public TheFox(string id, string name)
      {
        _Name = name;
        _Id = id;
      }

      public string Id
      {
        get { return _Id; }
      }

      public string Name
      {
        get { return _Name; }
      }
}

This should allow for the same usage but offers comparability with newton.


Your class is not appropriate for client side operation. You need to use DataContractAttribute to the class and DataMemberAttribute attribute to the members you want to serialize.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜