Deserializing JSON with Unknown Object Names

Deserializing JSON with unknown object names

It looks like you should be able to just get rid of your Measures class. Instead, put the dictionary straight into your Body class:

public class Body
{
public string _id { get; set; }
public Place place { get; set; }
public int mark { get; set; }
public Dictionary<string, SingleModule> measures { get; set; }
public string[] modules { get; set; }
}

As a separate matter, I'd strongly recommend following .NET naming conventions for your properties, and using [JsonProperty("measures")] etc to indicate to Json.NET how to translate your properties into JSON.

Deserialize json with known and unknown fields

An even easier option to tackling this problem would be to use the JsonExtensionDataAttribute from JSON .NET

public class MyClass
{
// known field
public decimal TaxRate { get; set; }

// extra fields
[JsonExtensionData]
private IDictionary<string, JToken> _extraStuff;
}

There's a sample of this on the project blog here

UPDATE Please note this requires JSON .NET v5 release 5 and above

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

You can create a custom JsonConverter to convert Sensor objects to concrete derived classes. Here's a working example of such a 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();
}

Then, when deserializing, you will have to add your custom converter to the settings in order for this to work.

Note that your Sensors property is get-only at the moment. You will have to provide a setter in order for NewtonSoft to populate the property.



Related Topics



Leave a reply



Submit