I am trying to use a json converter without success.
I have a sensor class which can (de)serialize json:
internal class JsonSensor<T> : IJsonSensor where T : struct
{
[JsonProperty(PropertyName = "value")]
public T Value { get; set; }
[JsonProperty(PropertyName = "state")]
public SensorState State { get; set; } = SensorState.Unknown;
public override string ToString()
{
return $"Value={Value}; State={State}";
}
}
Then I have a long list of sensors, I'll focus on the first one so ignore the rest for sake of simplicity:
[Function(Name = "sensors")]
internal class Sensors
{
[CabinetDoubleSensor(DisplayName=CabinetSensorNames.RcwPcwSupPrs, SensorType = SensorType.PressureInBar, Precision=2)]
[JsonProperty(PropertyName = "IO_PCW_FL_SPR")]
[JsonConverter(typeof(BarToPascalConverter))]
public JsonSensor<double> IOPcwFlSpr { get; set; } = new JsonSensor<double>();
[CabinetDoubleSensor(DisplayName=CabinetSensorNames.RcwPcwRetPrs, SensorType = SensorType.PressureInBar, Precision=2)]
[JsonProperty(PropertyName = "IO_PCW_RL_SPR")]
[JsonConverter(typeof(BarToPascalConverter))]
public JsonSensor<double> IOPcwRlSpr { get; set; } = new JsonSensor<double>();
...
...
...
}
And, I have converters that convert the value from one metric system to another. E.g. the BarToPascal
converter:
internal class BarToPascalConverter : FactorConverterBase
{
public BarToPascalConverter() : base(1e5)
{
}
}
internal abstract class FactorConverterBase : JsonConverter<JsonSensor<double>>
{
public double Factor { get; protected set; }
protected FactorConverterBase(double factor)
{
Factor = factor;
}
public override void WriteJson(JsonWriter writer, JsonSensor<double> value, JsonSerializer serializer)
{
writer.WriteValue(value);
}
public override JsonSensor<double> ReadJson(JsonReader reader, Type objectType, JsonSensor<double> existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
var o = reader.Value;
//existingValue.Value = ((JsonSensor<double>)reader.Value).Value / Factor;
return new JsonSensor<double>();
}
}
The problem is in the ReadJson method. There I am doing something wrong which leads to the following exception:
Newtonsoft.Json.JsonSerializationException : Additional text found in JSON string after finishing deserializing object. Path '', line 1, position 45.
I wrote a unit test to isolate the problem, and try different implementations for the ReadJson method, but I found that even when I 'just return' a new JsonSensor<double>()
deserializing still fails.
Of course, when I remove the JsonConverter, I can deserialize the string. So that tells me :
- the supplied json string is OK.
- the class structure for json deserialization is OK.
What am I doing wrong in the ReadJson? How can I successfully read the JsonSensor<double>
from the reader, and convert its value?
For completeness the unit test:
[TestFixture]
public class GetSensorsTests
{
[Test]
public void GetSensors()
{
const string test = "{\"IO_PCW_FL_SPR\" : {\"value\":123.0,\"state\":1}}";
var sensors = JsonConvert.DeserializeObject<Sensors>(test);
Assert.AreEqual(123.0, sensors.IOPcwFlSpr.Value, 0.00001);
}
}