简体   繁体   中英

Deserializing JSON to a property with type “object”

Well, I'm trying to serialize and save an object to JSON format and then deserialize the same object in C#. The object class is as follows:

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

I cannot use concrete classes instead of the object for the type of Props since the type is different among different objects. When I Serialize the object, I use a derived type to fill Props property. The result is well-structured in the JSON file. But when I deserialize it, it returns null for Props property while other properties are deserialized successfully.

The json deserialiser cannot establish what type to deserialise to Props to. When you serialise it knows the type so it serialises as expected.

If you make NodeModel generic:

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

you could then help the desrialiser by telling it what type to use.

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

Impossibility of the task with object

Let's imagine that that the desrialiser has the power to scan all the possible classes. Even then, it won't be able to make the right decision in many cases.

Consider the following scenario.

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?

}

Use JSONConvert?

Unless I misunderstood the question completely you want the type used in the class set to the property "Prop" in this scenario you receive the type of class added. Otherwise I am misunderstanding the question in it's entirety.

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

Thanks to the comment of Martin https://stackoverflow.com/users/1882699/martin-staufcik Changing the type of Props to JObject helped me get the value of Props .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM