C# Newtonsoft.Json.Linq.JValue always returning Int64

后端 未结 2 1332
不知归路
不知归路 2020-12-20 01:13

I am using the Newtonsoft.Json assembly to de-serialize a Json string into a dynamic object (ExpandoObject). The problem I am having is the int value is always returned as a

2条回答
  •  没有蜡笔的小新
    2020-12-20 01:29

    Cross-linking to answer https://stackoverflow.com/a/9444519/1037948

    From How do I change the default Type for Numeric deserialization?

    Paraphrased:

    • The author intentionally chose that all int's come back as Int64 to avoid overflow errors, and it's easier to check (for Json.NET internals, not you)
    • You can get around this with a custom converter like the one posted in the linked answer.

    Here's a really generic converter; not entirely sure about the CanConvert check, but the important part that worked for me was allowing typeof(object):

    /// 
    /// To address issues with automatic Int64 deserialization -- see https://stackoverflow.com/a/9444519/1037948
    /// 
    public class JsonInt32Converter : JsonConverter
    {
        #region Overrides of JsonConverter
    
        /// 
        /// Only want to deserialize
        /// 
        public override bool CanWrite { get { return false; } }
    
        /// 
        /// Placeholder for inheritance -- not called because  returns false
        /// 
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // since CanWrite returns false, we don't need to implement this
            throw new NotImplementedException();
        }
    
        /// 
        /// Reads the JSON representation of the object.
        /// 
        /// The  to read from.Type of the object.The existing value of object being read.The calling serializer.
        /// 
        /// The object value.
        /// 
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return (reader.TokenType == JsonToken.Integer)
                ? Convert.ToInt32(reader.Value)     // convert to Int32 instead of Int64
                : serializer.Deserialize(reader);   // default to regular deserialization
        }
    
        /// 
        /// Determines whether this instance can convert the specified object type.
        /// 
        /// Type of the object.
        /// 
        /// true if this instance can convert the specified object type; otherwise, false.
        /// 
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Int32) ||
                    objectType == typeof(Int64) ||
                    // need this last one in case we "weren't given" the type
                    // and this will be accounted for by `ReadJson` checking tokentype
                    objectType == typeof(object)
                ;
        }
    
        #endregion
    }
    

提交回复
热议问题