JsonConvert.DeserializeObject 将具有十六进制值的 JSON 反序列化为 sbyte 属性 时抛出异常
JsonConvert.DeserializeObject throws an exception when deserializing JSON with a hex value into an sbyte property
我有一个机器生成的 class MyData
,其中有 sbyte
个成员。实际的 class 很长而且可读性不是很好,但这里是它的一个片段:
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
?
您遇到异常是因为 Json.Net 在幕后为 sbyte
使用的转换方法是范围检查的,但您真正需要的是未经检查的转换(或更准确地说,一个范围更大)。您可以像这样使用自定义 JsonConverter
来处理它:
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
,如下所示:
var deserialized = JsonConvert.DeserializeObject<List<MyData>>(JsonStr, new SByteConverter());
我有一个机器生成的 class MyData
,其中有 sbyte
个成员。实际的 class 很长而且可读性不是很好,但这里是它的一个片段:
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
?
您遇到异常是因为 Json.Net 在幕后为 sbyte
使用的转换方法是范围检查的,但您真正需要的是未经检查的转换(或更准确地说,一个范围更大)。您可以像这样使用自定义 JsonConverter
来处理它:
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
,如下所示:
var deserialized = JsonConvert.DeserializeObject<List<MyData>>(JsonStr, new SByteConverter());