【问题标题】:Deserializing JSON to a property with type "object"将 JSON 反序列化为“object”类型的属性
【发布时间】:2020-02-19 07:08:55
【问题描述】:

好吧,我正在尝试序列化对象并将其保存为 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 属性返回 null 而其他属性反序列化成功。

【问题讨论】:

  • 如果你不知道类型是什么,你希望用它做什么?
  • 您可以使用自定义转换器并手动加载所有内容,但需要有某种方法来检测已通过属性名称序列化为 json 的类型。
  • 当我序列化对象时 - 你使用的是什么序列化程序?您能否分享一个minimal reproducible example,展示您如何序列化和反序列化您的NodeModel
  • 您可以将Props的类型更改为JObject
  • 它使用JObject 工作。谢谢@MartinStaufcik

标签: c# json object deserialization


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 还是不知道Props是什么类型
    • JsonConvert.SerializeObject(nodeModel, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }) 设置对象属性的类型。
    【解决方案3】:

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

    如果您将NodeModel 设为通用:

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

    【讨论】:

    • 问题是我有一个更大的模型要反序列化,其中包含许多 NodeModels 和其他超级模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多