将具有十六进制值的JSON反序列化为sbyte属性时,JsonConvert.DeserializeObject引发异常

时间:2019-07-25 17:03:18

标签: c# json reflection json.net jsonconverter

我有一个机器生成的类MyData,它具有sbyte个成员。实际的类很长,而且可读性很差,但这是其中的一部分:

class MyData
{
    private sbyte _MuxControl;
    public sbyte MuxControl 
    { 
        get { return _MuxControl; } 
        set { __isset.MuxControl = true; this._MuxControl = value; }
    }
}

相应的简化JSON如下所示:

[ 
  { 
    "MuxControl": 0xAA
  }
]

我正在尝试反序列化:

var deserialized = JsonConvert.DeserializeObject<List<MyData>>(JsonStr);

某些值超出了sbyte的范围,例如0xAA。结果,引发了异常。例如,当我将值更改为0x1时,它就可以工作。

我无法触摸MyData的代码。它是机器生成的。是否有转换设置,替代值或其他方法可以将这些值正确反序列化为sbyte

1 个答案:

答案 0 :(得分:1)

您之所以会遇到异常,是因为Json.Net在function conditionalMap(element, fn) { if (Array.isArray(element)) { return element.map(fn) } else { return fn(element) } } 的幕后使用的转换方法经过范围检查,但您真正需要的是未经检查的转换(或更准确地说,是更大的范围)。您可以使用自定义JsonConverter来处理,例如:

sbyte

要使用转换器,请将其实例传递给public class SByteConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(sbyte); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Integer) { // Integer values come in as longs from the reader. long val = (long)reader.Value; // If the value fits in 8 bits, convert it to a signed byte. if (val >= -128 && val <= 255) { return unchecked((sbyte)val); } // We got a value that can't fit in an sbyte. throw new JsonSerializationException("Value was out of range for an sbyte: " + val); } // We got something we didn't expect, like a string or object. throw new JsonSerializationException("Unexpected token type: " + reader.TokenType); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // Write sbyte values out in the same format we read them. // Note this is technically invalid JSON per the spec. writer.WriteRawValue("0x" + ((sbyte)value).ToString("X2")); } } ,如下所示:

JsonConvert.DeserializeObject

正在运行的演示:https://dotnetfiddle.net/fEW6wy