当前位置:  开发笔记 > 编程语言 > 正文

JSON反序列化 - 字符串自动转换为Int

如何解决《JSON反序列化-字符串自动转换为Int》经验,为你挑选了1个好方法。

当我将JSON取消病毒化到下面的C#对象时,无论是显式地使用Newtonsoft还是通过ASP.NET Web Api的模型绑定机制,字符串id值都会自动转换为int.我希望它会抛出异常或引发错误,因为存在类型不匹配.这是JSON应该如何在规范中工作?如果没有,我该如何防止这种自动转换?

JSON:{"id":"4", "name":"a"} C#模型:int id; string name



1> dbc..:

这是Json.NET的一个特性:在反序列化基本类型时,它会尽可能地将原始JSON值转换为目标c#类型.由于字符串"4"可以转换为整数,因此反序列化成功.如果您不需要此功能,可以为整数类型创建自定义JsonConverter,以检查正在读取的标记是否真的是数字(或者null,对于可以为空的值):

public class StrictIntConverter : JsonConverter
{
    readonly JsonSerializer defaultSerializer = new JsonSerializer();

    public override bool CanConvert(Type objectType) 
    {
        return objectType.IsIntegerType();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.Integer:
            case JsonToken.Float: // Accepts numbers like 4.00
            case JsonToken.Null:
                return defaultSerializer.Deserialize(reader, objectType);
            default:
                throw new JsonSerializationException(string.Format("Token \"{0}\" of type {1} was not a JSON integer", reader.Value, reader.TokenType));
        }
    }

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

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

public static class JsonExtensions
{
    public static bool IsIntegerType(this Type type)
    {
        type = Nullable.GetUnderlyingType(type) ?? type;
        if (type == typeof(long)
            || type == typeof(ulong)
            || type == typeof(int)
            || type == typeof(uint)
            || type == typeof(short)
            || type == typeof(ushort)
            || type == typeof(byte)
            || type == typeof(sbyte)
            || type == typeof(System.Numerics.BigInteger))
            return true;
        return false;
    }        
}

请注意,转换器接受的值如4.00整数.您可以通过删除检查JsonToken.Float是否不符合您的需要来更改此设置.

您可以直接将其应用于您的模型,如下所示:

public class RootObject
{
    [JsonConverter(typeof(StrictIntConverter))]
    public int id { get; set; }

    public string name { get; set; }
}

或者包含转换器JsonSerializerSettings以将其应用于所有积分字段:

var settings = new JsonSerializerSettings
{
    Converters = { new StrictIntConverter() },
};
var root = JsonConvert.DeserializeObject(json, settings);

最后,要在Web API中全局应用JSON序列化程序设置,请参阅此处.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有