[英]JSon.NET deserializing object doesn't work
So I have a Client-Server application that is using this class for communication, it contains an object so I can send any kind of data between server and client: 因此,我有一个使用此类进行通信的客户端-服务器应用程序,它包含一个对象,因此我可以在服务器和客户端之间发送任何类型的数据:
public class comObj
{
public eDisconnectedReason dcReason;
public object payload;
}
Before sending it through the Socket I will serialize it using JSon.Net, eg: 在通过套接字发送之前,我将使用JSon.Net将其序列化,例如:
string jsonString = JsonConvert.SerializeObject((new Common.comObj() { dcReason = Server.disconnectedReason, payload = Data }), Formatting.None);
now the server receives exactly the string that was sent by the client: 现在服务器完全接收到客户端发送的字符串:
sent string: "{\"dcReason\":4,\"payload\":{\"msg\":\"hi\"}}"
received string: "{\"dcReason\":4,\"payload\":{\"msg\":\"hi\"}}"
however when I try to deserialize the received string into the original comObj: 但是,当我尝试将接收到的字符串反序列化为原始comObj时:
Common.comObj rcvdObj = JsonConvert.DeserializeObject<Common.comObj>(rcvdString);
rcvdObj.payload is of type Newtonsoft.Json.Linq.JObject instead of object. rcvdObj.payload的类型为Newtonsoft.Json.Linq.JObject,而不是object。
Let us start by considering your JSON input: 让我们首先考虑您的JSON输入:
{
"dcReason": 4,
"payload": {
"msg": "hi"
}
}
Using Json.NET you have two key ways of deserializing JSON data. 使用Json.NET,您有两种反序列化JSON数据的关键方法。 You can:
您可以:
JToken
type. JToken
类型。 (In your case, it instantiates a JObject
-- a subclass of JToken
-- because JSON.Net recognized that the JSON input specified an object, as opposed to a primitive type or an array) JObject
-的一个子类JToken
-因为JSON.Net认识到,JSON输入指定的对象,而不是一个基本类型或阵列) In your case, you actually ended up with a hybrid of both approaches. 在您的情况下,您实际上最终混合了这两种方法。 Since you specified a specific type for the root object, it returned an instance of
comObj
. 由于您为根对象指定了特定类型,因此它返回了
comObj
的实例。 Since you merely specified object
as the type of the property payload
, Json.NET did its best and simply reverted to option 2) and gave you an instance of JObject
, which contains the data such as msg
. 由于您仅将
object
指定为属性payload
的类型,因此Json.NET会尽力而为,并简单地恢复为选项2),并为您提供一个JObject
实例,其中包含msg
等数据。
You have two options to solve your problem. 您有两种选择来解决您的问题。 You can:
您可以:
payload
property as a JObject
, like you would have had to do for the entire JSON body if you had not used option 1). payload
属性查询为JObject
,就像如果您不使用选项1)一样,必须对整个JSON主体执行操作。 payload
property. payload
属性。 I strongly recommend this approach, as it is considerably more typesafe and also easier to work with. To achieve the former, you can use faclities such as o["msg"]
-- essentially like a dictionary. 要实现前者,您可以使用诸如
o["msg"]
-本质上就像字典。
To achieve the latter -- which I would recommmend -- simply define a type for payload
. 要实现后者(我建议),只需定义
payload
的类型。 In other words, change you code to: 换句话说,将您的代码更改为:
public class comObj
{
public eDisconnectedReason dcReason;
public Payload payload;
}
public class Payload
{
public string msg { get; set; }
}
Now when you deserialize your JSON, you'll be able to use the syntax: 现在,当您反序列化JSON时,就可以使用以下语法:
Console.WriteLine(rcvdObj.payload.msg);
And -- importantly -- if you later decide to rename msg
in your JSON payload to, say, message
you will be able to properly refactor the property msg
of payload to message
and expect all usages to be fixed. 而且-重要的是-如果您以后决定将JSON有效负载中的
msg
重命名为message
那么您将能够正确地将有效负载的msg
属性重构为message
并期望所有用法都将得到修复。 This is obviously less robust when using strings. 使用字符串时,这显然不那么健壮。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.