JSON 反序列化程序不适用于嵌套对象

JSON Deserializer not working for nested object

提问人:user14267126 提问时间:10/13/2023 最后编辑:Yong Shunuser14267126 更新时间:10/13/2023 访问量:55

问:

我有一个应用程序,可以序列化一个对象并发送一个JSON字符串值,如下所示。

public class Rootobject
{
    public int MessageState { get; set; }
    public object Message { get; set; }
    public object HeaderId { get; set; } 
}

public class Message
{
    public string FName { get; set; }
    public string LName { get; set; }
    public string Address { get; set; }       
}

Rootobject ro = new Rootobject();
ro.HeaderId = "HID";
ro.MessageState = 0;
ro.Message = new Message() { FName = "john", LName = "Doe", Address = "123456" };

string x = JsonConvert.SerializeObject(ro);

此值将发送到另一个应用程序,并按如下所示进行反序列化。x

public class Rootobject1
{
    public int MessageState { get; set; }
    public object Message { get; set; }
    public object HeaderId { get; set; }
}

public class Message1
{
    public string FName { get; set; }
    public string LName { get; set; }
    public string Address { get; set; }
}

var y = JsonConvert.DeserializeObject<Rootobject1>(receivedMsg);

在这里,嵌套对象对我来说没有被反序列化,只是一个.JObject

deserializedobj

如何反序列化嵌套对象?请帮忙。

谢谢。

C# json.net JSON 反序列化

评论

0赞 Yong Shun 10/13/2023
旁注:用数字命名类并声明变量,如果没有一个可理解的、有意义的名称,这不是一个好的编码实践。Message1xy
0赞 Panagiotis Kanavos 10/13/2023
对象根本不嵌套。当代码告诉反序列化程序只创建一个 .反序列化程序工作正常,因为所有 .NET 开发人员(包括您)都可以验证。StackOverflow 是一个 ASP.NET Core 应用程序Messageobject
1赞 Panagiotis Kanavos 10/13/2023
it just a JObject.这是预期的,实际上是合乎逻辑的行为。由于应用程序不需要任何特定类型,因此反序列化程序会创建一个动态 JObject 实例,该实例提供对该属性中的属性和嵌套对象的访问

答:

3赞 Yong Shun 10/13/2023 #1

我看不出将属性定义为类型的原因,因为您知道数据结构。MessageRootobject1object

解决此问题的快速方法是使用类型进行定义。MessageMessage1

public class Rootobject1
{
    public int MessageState { get; set; }
    public Message1 Message { get; set; }
    public object HeaderId { get; set; }
}

或者,您可以考虑将 转换为类型。JObjectMessage1

var message = ((JObject)y.Message).ToObject<Message1>();

评论

0赞 Trinitrotoluol 10/13/2023
第一种方法是更有效的方法,避免不必要的强制转换。
1赞 JonasH 10/13/2023 #2

当库尝试反序列化消息时,它不知道它应该是什么类型。Json 只是一个属性树,没有任何指示应该反序列化为 .Json 将检查 以找出它应该使用的各种类型,但如果你只有 -property,则没有类型信息可以继续。MessageMessage1Rootobject1object

有几种解决方案

使用实际类型

public Message1 Message { get; set; }

如果对象模型允许,这是迄今为止处理问题的最简单和最好的方法。

指定类型名称处理

string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
})

这使得序列化程序发出一个属性,它可以使用该属性来重新构造正确的类型。但我要警告不要这样做,默认情况下它包含完整的命名空间,这使得重命名和移动类型变得困难,并且可能导致安全问题。System.Text.Json 使用属性来指定类型名称,这是我非常喜欢的方法。$type="<typename>"

手动解析 json

您可以使用 JsonTextReader 来解析 json 树,并对其进行任何您想要的事情。这允许高度的灵活性,但使用起来最麻烦。