[英]JsonConvert.DeserializeObject throws an exception when deserializing JSON with a hex value into an sbyte property
I have a machine-generated class MyData
which has sbyte
members. 我有一个机器生成的类
MyData
,该类具有sbyte
成员。 The actual class is long and not very readable, but here is a fragment of it: 实际的类很长,而且可读性很差,但这是其中的一部分:
class MyData
{
private sbyte _MuxControl;
public sbyte MuxControl
{
get { return _MuxControl; }
set { __isset.MuxControl = true; this._MuxControl = value; }
}
}
The corresponding simplified JSON looks like this: 相应的简化JSON如下所示:
[
{
"MuxControl": 0xAA
}
]
I am attempting to deserialize like this: 我试图像这样反序列化:
var deserialized = JsonConvert.DeserializeObject<List<MyData>>(JsonStr);
Some values exceed sbyte
range, for example 0xAA
. 一些值超出了
sbyte
范围,例如0xAA
。 As a result, exceptions are thrown. 结果,引发了异常。 When I change the value to
0x1
, for example, it works. 例如,当我将值更改为
0x1
,它可以工作。
I can not touch the code of MyData
. 我无法触摸
MyData
的代码。 It's machine-generated. 它是机器生成的。 Is there a conversion setting, override or some other way to get these values to deserialize properly into
sbyte
? 是否有转换设置,替代或其他方法来获取这些值以正确反序列化为
sbyte
?
You are getting the exception because the conversion methods Json.Net is using under the covers for sbyte
are range checked, but what you really need here is an unchecked conversion (or more precisely, a bigger range). 之所以会出现异常,是因为Json.Net在
sbyte
幕后使用的转换方法经过范围检查,但是这里真正需要的是未经检查的转换(或更准确地说,是更大的范围)。 You can handle that with a custom JsonConverter
like so: 您可以使用自定义
JsonConverter
来处理, 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"));
}
}
To use the converter, pass an instance of it to JsonConvert.DeserializeObject
like this: 要使用转换器,
JsonConvert.DeserializeObject
其实例传递给JsonConvert.DeserializeObject
如下所示:
var deserialized = JsonConvert.DeserializeObject<List<MyData>>(JsonStr, new SByteConverter());
Working demo: https://dotnetfiddle.net/fEW6wy 工作演示: https : //dotnetfiddle.net/fEW6wy
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.