简体   繁体   English

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

[英]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.

相关问题 JsonConvert.DeserializeObject 在反序列化 CouchBase 响应时抛出异常 - JsonConvert.DeserializeObject throws exception when deserializing CouchBase response 反序列化为数据集时,JsonConvert.DeserializeObject 不起作用 - JsonConvert.DeserializeObject is not working when deserializing to a DataSet JsonConvert.DeserializeObject <DataTable> 引发异常 - JsonConvert.DeserializeObject<DataTable> throws an exception JsonConvert.DeserializeObject()抛出StackOverflow异常 - JsonConvert.DeserializeObject() throws StackOverflow exception 使用 JsonConvert.DeserializeObject (Newtonsoft.Json) 反序列化时丢失不可打印的 ascii 字符(组分隔符) - Losing non printable ascii character (group separator) when deserializing with JsonConvert.DeserializeObject (Newtonsoft.Json) 在JsonConvert.DeserializeObject中反序列化对象时出现意外的标记 - Unexpected token when deserializing object in JsonConvert.DeserializeObject 尝试将byte []反序列化为IEnumerable时,JsonConvert.DeserializeObject引发异常<byte> - JsonConvert.DeserializeObject throws an exception when attempting to deserialize byte[] to IEnumerable<byte> 反序列化字符串时出现 JsonConvert.DeserializeObject 错误 - JsonConvert.DeserializeObject error while deserializing a string JsonConvert.DeserializeObject &lt;&gt;(字符串)为$ id属性返回空值 - JsonConvert.DeserializeObject<> (string) returns null value for $id property Json.NET JsonConvert.DeserializeObject() 返回值 null - Json.NET JsonConvert.DeserializeObject() return null value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM