将JSON反序列化为类型为“对象”的属性

时间:2019-10-23 05:28:53

标签: c# json object deserialization

好吧,我正在尝试序列化对象并将其保存为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类型的对象,因为不同对象之间的类型是不同的。当我序列化对象时,我使用派生类型来填充Props属性。结果在JSON文件中结构良好。但是,当我反序列化时,Props属性返回null,而其他属性成功反序列化。

3 个答案:

答案 0 :(得分:1)

json反序列化器无法确定要反序列化为Props的类型。当您进行序列化时,它知道类型,因此可以按预期进行序列化。

如果您将NodeModel设为通用:

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

然后您可以通过告诉它使用哪种类型来帮助desrialiser。

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

使用object的任务不可能

让我们想象一下,desrialiser可以扫描所有可能的类。即使那样,在很多情况下它也无法做出正确的决定。

请考虑以下情形。

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?

}

答案 1 :(得分:1)

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

答案 2 :(得分:0)

感谢Martin https://stackoverflow.com/users/1882699/martin-staufcik的评论,将Props的类型更改为JObject有助于我获得Props的价值。