当我将 JSON 反序列化为下面的 C# 对象时,无论是显式使用 Newtonsoft 还是通过 ASP.NET Web Api 的模型绑定(bind)机制,字符串 id
值都会自动转换为 int。我希望它会抛出异常或引发错误,因为存在类型不匹配。这就是 JSON 在规范中的工作方式吗?如果没有,我该如何防止这种自动转换?
JSON:{"id":"4", "name":"a"}
C# 模型:int id;字符串名称
最佳答案
这是 Json.NET 的一个特性:当反序列化原始类型时,它会尽可能将原始 JSON 值转换为 objective-c # 类型。由于字符串"4"
可以转化为整数,所以反序列化成功。如果你不想要这个功能,你可以创建一个 custom JsonConverter
对于检查正在读取的标记是否真的是数字的整数类型(或 null
,对于可为 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<RootObject>(json, settings);
最后,要在 Web API 中全局应用 JSON 序列化程序设置,请参见示例 here .
关于c# - JSON反序列化——String自动转为Int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41783225/