簡體   English   中英

C#Newtonsoft JSON-使用未知對象的集合反序列化對象

[英]C# Newtonsoft JSON - Deserializing Object with collection of unknown objects

我正在努力使用newtonsoft.json對json文件進行反序列化。
我要反序列化的對象如下所示:

public class Device
{
        public string Name { get; set; }
        public int Id { get; set; }
        public string Type { get; set; }

        public List<Sensor> Sensors { get; }

        public bool IsPaired { get; set; }

}

傳感器類是虛擬的。
我有多個類繼承自Sensor類(TemperatureSensor,WaterLevelSensor等),並添加了一些新屬性。 這些類的實例存儲在Sensors集合中。

Json文件如下所示:

[  
   {  
      "Name":"Device1",
      "Id":0,
      "Type":"TemperatureSensor",
      "Sensors":[  
         {  
            "Id":0,
            "Type":"TemperatureSensor",
            "Data":18.136218099999997,
            "ReadIntervalInMiliseconds":5000
         },
         {  
            "Id":1,
            "Type":"TemperatureSensor",
            "Data":18.0999819,
            "ReadIntervalInMiliseconds":5000
         }
      ],
      "IsPaired":false
   },
   {  
      "Name":"Device2",
      "Id":1,
      "Type":"AutomaticGate",
      "Sensors":[  
         {  
            "OpenPercentage":0,
            "Id":0,
            "Type":"AutomaticGate",
            "Data":0.0,
            "ReadIntervalInMiliseconds":0
         }
      ],
      "IsPaired":false
   },
   {  
      "Name":"Device3",
      "Id":2,
      "Type":"Other",
      "Sensors":[  
         {  
            "IsActive":false,
            "Id":0,
            "Type":"AirConditioner",
            "Data":0.0,
            "ReadIntervalInMiliseconds":0
         },
         {  
            "Id":1,
            "Type":"LightSensor",
            "Data":4.0,
            "ReadIntervalInMiliseconds":5000
         }
      ],
      "IsPaired":false
   }
]

我假設我必須從json文件讀取Sensor的“類型”,並在此基礎上創建Object並將其添加到某個集合中,然后使用該集合返回Device類對象。

我試圖像在本文中那樣制作自定義JsonConverter,但收效甚微。

您可以創建一個自定義JsonConverter來將Sensor對象轉換為具體的派生類。 這是一個這樣的JsonConverter的工作示例:

public class SensorConverter : JsonConverter
{
    public override bool CanRead => true;
    public override bool CanWrite => false;
    public override bool CanConvert(Type objectType)
    {
        // Don't do IsAssignableFrom tricks here, because you only know how to convert the abstract class Sensor.
        return objectType == typeof(Sensor);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);
        string sensorType = jObject["Type"].Value<string>();
        switch (sensorType)
        {
            case "TemperatureSensor":
                return jObject.ToObject<TemperatureSensor>(serializer);
            case "AutomaticGate":
                return jObject.ToObject<AutomaticGate>(serializer);
            case "AirConditioner":
                return jObject.ToObject<AirConditioner>(serializer);
            case "LightSensor":
                return jObject.ToObject<LightSensor>(serializer);
            default:
                throw new NotSupportedException($"Sensor type '{sensorType}' is not supported.");
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}

然后,在反序列化時,您必須將自定義轉換器添加到設置中,以使其工作。

請注意,您的“ Sensors屬性目前為只讀。 您將必須提供一個setter,以便NewtonSoft可以填充該屬性。

另一個需要更少代碼的解決方案是使用JsonSubTypes

假設有一個抽象的Sensor類,則需要通過自定義屬性注冊一個已知的子類及其標識符。 因此,在您的情況下,標識符是名為"Type"屬性,而類映射在KnownSubType屬性中。

[JsonConverter(typeof(JsonSubtypes), "Type")]
[JsonSubtypes.KnownSubType(typeof(TemperatureSensor), "TemperatureSensor")]
[JsonSubtypes.KnownSubType(typeof(WaterLevelSensor), "WaterLevelSensor")]
[JsonSubtypes.KnownSubType(typeof(AirConditioner), "AirConditioner")]
[JsonSubtypes.KnownSubType(typeof(AutomaticGate), "AutomaticGate")]
[JsonSubtypes.KnownSubType(typeof(LightSensor), "LightSensor")]
public abstract class Sensor
{
}

在您的Device類中, Sensors屬性必須具有set屬性。

public List<Sensor> Sensors { get; set;}

用法:

var items = JsonConvert.DeserializeObject<List<Device>>(json);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM