根据 C 语言中的 JSON 内容将 JSON 反序列化为不同的对象类型#

Deserialize JSON to different Object Types based on JSON content in C#

提问人:dobre.b 提问时间:1/31/2022 最后编辑:dobre.b 更新时间:2/3/2022 访问量:1526

问:

因此,我开发了一个由 IoT 中心触发的 Azure 函数,以便从设备接收消息。 我想将它们(以 JSON 形式从设备接收的消息)反序列化为不同的对象类型(obs.我不被允许更改消息的语法)。有没有办法根据我收到的消息反序列化为正确的对象类型?

  • 方案 1:如果消息具有以下语法,则反序列化应为 ReadResponseMessage 类型。

    string JsonMessageFromDevice = "{"device_id":"DeviceTest","message_id":0,"port":3,"portValue":false,"time":"2021-08-25 10:18:51","response_status":"Send"}";
    ReadResponseMessage MessageReceivedType1 = JsonConvert.DeserializeObject<ReadResponseMessage>(JsonMessageFromDevice);
    
  • 方案 2:如果消息具有以下语法,则反序列化应为 EventMessage 类型。

    string JsonMessageFromDevice = "{"device_id":"DeviceTest","message_id":1501,"port1":false,"port2":false,"time":"2021-08-25 10:22:02","response_status":"OK"}";
    EventMessage MessageReceivedType2 = JsonConvert.DeserializeObject<EventMessage>(JsonMessageFromDevice);
    

哪里:

class ReadResponseMessage  {
     
      [JsonProperty("device_id")]
      public string DeviceID {get; set;}

      [JsonProperty("message_id")]
      public int MessageID {get; set;}

      [JsonProperty("port")]
      public int Port{get; set;}

      [JsonProperty("portValue")]
      public bool PortValue {get; set;}

      [JsonProperty("time")]
      public DateTime Time {get; set;}

      [JsonProperty("response_status")]
      public string ResponseStatus{get; set;}
 
}

和:

class EventMessage {

      [JsonProperty("device_id")]
      public string DeviceID {get; set;}

      [JsonProperty("message_id")]
      public int MessageID {get; set;}

      [JsonProperty("port1")]
      public bool Port1{get; set;}

      [JsonProperty("port2")]
      public bool Port2 {get; set;}

      [JsonProperty("time")]
      public DateTime Time {get; set;}

      [JsonProperty("response_status")]
      public string ResponseStatus{get; set;}

}
C# JSON 反序列化 对象类型

评论

0赞 Poul Bak 1/31/2022
好吧,你只需要找到json字符串之间的差异并为此进行测试。然后,您可以使用所需的类型。例如:。if (JsonMessageFromDevice.Contains("portValue")){ // use 'ReadResponseMessage '}
0赞 dobre.b 1/31/2022
是的,但这不是一个长期的解决方案,因为消息的数量和语法的复杂性会增加。

答:

1赞 Amjad S. 1/31/2022 #1
string JsonMessageFromDevice = "{"device_id":"DeviceTest","message_id":0,"port":3,"portValue":false,"time":"2021-08-25 10:18:51","response_status":"Send"}";

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(JsonMessageFromDevice);

var jobject = JObject.Parse(JsonMessageFromDevice);
   var result = jobject["port"];
   if (result != null)
   {
       ReadResponseMessage readResponseMessage = jobject.ToObject<ReadResponseMessage>();
   }
   else
   {
       EventMessage eventMessage = jobject.ToObject<EventMessage>();
   }

或更改型号

class ReadResponseMessage  {
     
      [JsonProperty("device_id")]
      public string DeviceID {get; set;}

      [JsonProperty("message_id")]
      public int MessageID {get; set;}

      [JsonProperty("port")]
      public Dictionary<String,bool> Port{get; set;} // or List<string> port

      [JsonProperty("time")]
      public DateTime Time {get; set;}

      [JsonProperty("response_status")]
      public string ResponseStatus{get; set;}
 
}

评论

1赞 dobre.b 1/31/2022
那么如何将oMycustomclassname转换为ReadResponseMessage呢?
0赞 Amjad S. 1/31/2022
该内容对您有帮助吗?否则请详细解释您的问题
0赞 dobre.b 1/31/2022
我必须跳到找到一种在不解释 JsonMessageFromDevice 中的值的情况下进行反序列化的方法。消息比此处显示的要复杂得多。也许如果我找到一种方法将动态对象投射到我的对象上。但是很酷,我现在有一个解决方案。谢谢!
0赞 Amjad S. 1/31/2022
好吧,我现在理解你了。是否可以将拥有的模型更改为单个类,然后添加属性列表<string>Ports