簡體   English   中英

將具有十六進制值的JSON反序列化為sbyte屬性時,JsonConvert.DeserializeObject引發異常

[英]JsonConvert.DeserializeObject throws an exception when deserializing JSON with a hex value into an sbyte property

我有一個機器生成的類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

之所以會出現異常,是因為Json.Net在sbyte幕后使用的轉換方法經過范圍檢查,但是這里真正需要的是未經檢查的轉換(或更准確地說,是更大的范圍)。 您可以使用自定義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"));
    }
}

要使用轉換器, JsonConvert.DeserializeObject其實例傳遞給JsonConvert.DeserializeObject如下所示:

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

工作演示: https : //dotnetfiddle.net/fEW6wy

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM