介尘部落

文学|音乐|休闲娱乐|计算机技术|地球科学|社会学——知识成就命运


c# – 如何让反序列化在非整数上抛出异常,期望一个int?Newtonsoft.Json JsonConverter的使用方法示例

Newtonsoft.Json在反序列化int的时候默认将空字符串识别为null,抛出异常。在WebApi的传参中是一个极大的困扰。问题就在于int.parse(“”)会报错。

下面是几种常见的数字转换场景:

> JsonConvert.DeserializeObject<int>(“4.5”)失败.
> JToken.Parse(“4.5”).ToObject<int>()成功并返回4.
> JsonConvert.DeserializeObject<uint>(“4.5”)成功并返回4.
> JsonConvert.DeserializeObject<long>(“4.5”)成功并返回4.

(实际上,将“4.5”直接反序列化为int似乎是唯一失败的情况.Json.NET将直接或间接地将“4.5”反序列化为任何其他整数类型.)

差异似乎是由于JsonTextReader.ParseReadNumber()(直接反序列化JSON时调用)和JsonReader.ReadAsInt32()(从JToken反序列化时调用)之间的不一致引起的.前者检查文本JSON值在反序列化为int时实际上是整数,而后者只是调用Convert.ToInt32(),它快乐地返回舍入值.

如果你愿意,你可以report an issue关于不一致.

与此同时,您有几个选项可以避免不一致.首先,您可以为尝试将浮点值反序列化为整数时抛出异常的整数引入自定义的JsonConverter,然后在从JToken层次结构反序列化时使用它。

下面是字符串转int的Converter类示例:

public class StrictIntConverter : StrictIntConverterBase
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(int) || objectType == typeof(int?);
    }
}

public abstract class StrictIntConverterBase : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType);
        bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);

        if (reader.TokenType == JsonToken.Null)
        {
            if (isNullable)
                return null;
            throw new JsonSerializationException(string.Format("Null value for {0}", objectType));
        }
        else if (reader.TokenType == JsonToken.Float)
        {
            throw new JsonSerializationException(string.Format("Floating-point value {0} found for {1}.", reader.Value, type));
        }
        else
        {
            // Integer or string containing an integer
            if (reader.Value.GetType() == type)
                return reader.Value;
            return JToken.Load(reader).ToObject(type);
        }
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

使用方法

var jsonSerializer = JsonSerializer.Create(myMediaTypeFormatters.JsonFormatter.SerializerSettings;
jsonSerializer.Converters.Add(new StrictIntConverter());    
j.ToObject<T>(jsonSerializer)

另外一种处理此问题的方法

阅读全文
公众号-介尘阅读时光
赞赏支持

0 Responses to “c# – 如何让反序列化在非整数上抛出异常,期望一个int?Newtonsoft.Json JsonConverter的使用方法示例”

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)