Десериализация JSON в свойство с типом «объект» - PullRequest
0 голосов
/ 23 октября 2019

Ну, я пытаюсь сериализовать и сохранить объект в формате JSON, а затем десериализовать тот же объект в C #. Класс объекта выглядит следующим образом:

public class NodeModel
{
    public double X { get; set; }
    public double Y { get; set; }
    public int ParentNumber { get; set; }
    public GeometryParams Geometry { get; set; }
    public object Props { get;  set; }
}

Я не могу использовать конкретные классы вместо объекта для типа реквизита, так как тип отличается у разных объектов. Когда я сериализую объект, я использую производный тип для заполнения свойства Props. Результат хорошо структурирован в файле JSON. Но когда я десериализую его, он возвращает ноль для свойства Props, тогда как другие свойства успешно десериализованы.

Ответы [ 3 ]

1 голос
/ 23 октября 2019

Использовать JSONConvert?

Если я не полностью понял вопрос, вы хотите, чтобы тип, используемый в классе, был установлен в свойство «Prop»; в этом сценарии вы получаете тип добавленного класса. В противном случае я неправильно понимаю вопрос целиком.

    public class TestClass
    {
        public string A = "";
    }
    public class NodeModel
    {
        public double X { get; set; }
        public double Y { get; set; }
        public int ParentNumber { get; set; }
        public GeometryParams Geometry { get; set; }
        public object Props { get; set; }
    }
    public class GeometryParams
    {
        public string PropTest { get; set; }
    }

        public void TestMethod()
    {

        var nodeModel = new NodeModel()
        {
            X = 3.5,
            Y = 4.2,
            ParentNumber = 1,
            Geometry = new GeometryParams { PropTest = "value" },
            Props = new TestClass()
        };

        var json = JsonConvert.SerializeObject(nodeModel, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All,  });

        //json result
        //{ 
            //"$type":"WebApplication2.Controllers.ValuesController+NodeModel, WebApplication2",
            //"X":3.5,
            //"Y":4.2,
            //"ParentNumber":1,
            //"Geometry":{ 
                //"$type":"WebApplication2.Controllers.ValuesController+GeometryParams, WebApplication2",
                //"PropTest":"value"},
            //"Props":{ 
                //"$type":"WebApplication2.Controllers.ValuesController+TestClass, WebApplication2",
                //"A":""} 
        //}
        var nodeModel2 = JsonConvert.DeserializeObject<NodeModel>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects });
     }
1 голос
/ 23 октября 2019

Десериализатор json не может установить тип десериализации до Props. Когда вы сериализуете, он знает тип, поэтому он сериализуется, как и ожидалось.

Если вы сделаете NodeModel generic:

public class NodeModel<T>
{
   (...)
   public T Props { get;  set; }
}

, вы можете помочь десриализатору, сообщив ему, какой тип использовать.

serialiser.DeserialiseObject<NodeModel<SomeType>>(json);

Невозможность задания с object

Давайте представим, что десериализатор обладает способностью сканировать все возможные классы. Даже тогда он не сможет принять правильное решение во многих случаях.

Рассмотрим следующий сценарий.

public class A
{
    public string Name { get; set; }
    public string Color { get; set; }
}

public class B
{
    public string Name { get; set; }
    public string Color { get; set; }
    public string X { get; set; }
}

public class NodeModel
{
    public object Props { get; set; }
}

public static void Main(string[] args)
{
  var o = new NodeModel { Props = new B() { Name = "I'm B", Color = "Blue", X = null}};

  var json = serialiser.Serialise(o);

  // Json would be something like 
  // {
  //  "Props": {
  //    "Name": "I\u0027m B",
  //    "Color": "Blue",
  //  }
  // }

  //(...)

  var o2 = serialiser.Deserialise(o); 

  // How can the serialiser decide what to deserialise Props to?
  // Is it A or is it B?

}
0 голосов
/ 23 октября 2019

Благодаря комментарию Мартина https://stackoverflow.com/users/1882699/martin-staufcik Изменение типа Props на JObject помогло мне получить значение Props.

...