0

我正在尝试使用 json 转换器但没有成功。

我有一个可以(反)序列化 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}";
    }
}

然后我有一长串传感器,我将专注于第一个,为了简单起见忽略其余的:

[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>();

    ...
    ...
    ...
}

而且,我有转换器可以将值从一种公制转换为另一种公制。例如BarToPascal转换器:

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>();
    }
}

问题出在 ReadJson 方法中。那里我做错了什么,导致以下异常:

Newtonsoft.Json.JsonSerializationException : 完成反序列化对象后在 JSON 字符串中找到的附加文本。路径 '',第 1 行,位置 45。

我编写了一个单元测试来隔离问题,并为 ReadJson 方法尝试不同的实现,但我发现即使我“只是返回”一个新的JsonSensor<double>()反序列化仍然失败。

当然,当我删除 JsonConverter 时,我可以对字符串进行反序列化。所以这告诉我:

  • 提供的 json 字符串是可以的。
  • json反序列化的类结构没问题。

我在 ReadJson 中做错了什么?我怎样才能成功阅读JsonSensor<double>从阅读器中读取并转换它的值?

为了完整性,单元测试:

[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);
    }
}
4

1 回答 1

0

这似乎可行,不确定这是否是它应该如何工作的预期方式。

    public override JsonSensor<double> ReadJson(JsonReader reader, Type objectType, JsonSensor<double> existingValue, bool hasExistingValue,
        JsonSerializer serializer)
    {
        var jsonObject=JObject.Load(reader);
        var s = JsonConvert.DeserializeObject<JsonSensor<double>>(jsonObject.ToString());
        s.Value = s.Value / Factor;
        return s;
    }

dbc 评论后更新:

    public override void WriteJson(JsonWriter writer, JsonSensor<double> value, JsonSerializer serializer)
    {
        value.Value = value.Value * Factor;
        var json = JsonConvert.SerializeObject(value);
        writer.WriteValue(json);
    }

    public override JsonSensor<double> ReadJson(JsonReader reader, Type objectType, JsonSensor<double> existingValue, bool hasExistingValue,
        JsonSerializer serializer)
    {
        var jsonSensor = JObject.Load(reader).ToObject<JsonSensor<double>>();
        jsonSensor.Value = jsonSensor.Value / Factor;
        return jsonSensor;
    }
于 2019-09-16T07:39:19.343 回答