Десериализация Защищенный построенный объект от JSON - PullRequest
3 голосов
/ 01 мая 2011

Я использую сериал Ньютона json.net.При десериализации JSON в «TheFox»;он входит в защищенный ctor и получает значения свойств по умолчанию.Но не значения свойств в строке json.Могу ли я решить эту проблему, не используя dto или какой-либо другой фреймворк?

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; }
    }
}

Это тест:

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

        var settings = new JsonSerializerSettings ()
        {
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
        };

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

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

Ответы [ 3 ]

0 голосов
/ 01 мая 2011
    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; }
      }
}

Это должно допускать такое же использование, но обеспечивает сопоставимость с ньютоном.

0 голосов
/ 01 мая 2011

Проверен источник в json.net и пока нет возможности.Потому что, если данное свойство доступно только для чтения, оно пропускает установку этапа значения.может потребоваться функция заполнения внутреннего поля.

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

Этот метод плохой, для его заполнения требуется экземпляр объекта, но он работает.

0 голосов
/ 01 мая 2011

Ваш класс не подходит для работы на стороне клиента. Вам необходимо использовать DataContractAttribute для класса и атрибут DataMemberAttribute для членов, которые вы хотите сериализовать.

...