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

C# JSON反序列化-字符串自动转换为Int,c#,json,asp.net-mvc,asp.net-web-api,json.net,C#,Json,Asp.net Mvc,Asp.net Web Api,Json.net,当我显式地使用Newtonsoft或通过ASP.NET Web Api的模型绑定机制将JSON解析为下面的C#对象时,字符串id值会自动转换为int。我希望它会抛出异常或引发错误,因为存在类型不匹配。这就是JSON在规范中的工作方式吗?如果没有,我如何防止这种自动转换 JSON:{“id”:“4”,“name”:“a”} C#模型:int-id;字符串名称如果你最终想要的话,试着把你的C#模型变成一个字符串。你描述的是一个特性,因为大多数人都想要这种行为。我没有检查,但我打赌它使用了类似于Con

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

JSON:
{“id”:“4”,“name”:“a”}

C#模型:
int-id;字符串名称

如果你最终想要的话,试着把你的C#模型变成一个字符串。

你描述的是一个特性,因为大多数人都想要这种行为。我没有检查,但我打赌它使用了类似于Convert.ChangeType(strValue,propertyType)的东西

如果您需要它作为字符串,请使用Maksim的解决方案

如果需要,您的模型还可以合并一个额外的属性以同时具有这两种类型:

public class Model
{
    public int id { get; set; }
    public string idStr => id.ToString();

    public string name { get; set; }
}

这是Json.NET的一个特性:当反序列化原语类型时,它将尽可能将原语Json值转换为目标c#类型。由于字符串
“4”
可以转换为整数,因此反序列化成功。如果不需要此功能,可以为整数类型创建一个值,用于检查正在读取的令牌是否为真正的数字(或为可空值创建一个
null
):

注意:转换器接受像
4.00
这样的值作为整数。如果
JsonToken.Float
不符合您的需要,您可以通过删除对它的检查来更改它

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

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

    public string name { get; set; }
}
或将转换器包括在中,以将其应用于所有积分场:

var settings = new JsonSerializerSettings
{
    Converters = { new StrictIntConverter() },
};
var root = JsonConvert.DeserializeObject<RootObject>(json, settings);
var设置=新的JsonSerializerSettings
{
转换器={new StrictIntConverter()},
};
var root=JsonConvert.DeserializeObject(json,设置);

最后,要在Web API中全局应用JSON序列化程序设置,请参见示例。

这是NewtonSoft等JSON序列化框架提供的功能。在JSON对象中,所有内容都是字符串。它是负责类型转换的框架。如果json字符串有“id”:“somestring”,它肯定会抛出一个错误。只要JSON字符串值是目标类型的格式,框架就会尝试进行类型转换。。。呵呵?不,{“a”:4}和{“a”:“4}是不同的。“a”一个是JSON数字,另一个是字符串。在JSON对象中,所有内容都不是字符串。属性可以是字符串、数字、其他属性或数组。将字符串解释为数字(在我看来,如果可以将其解析为数字,反序列化类型是数字,那么这并不是一个真正的问题。JSON类型是非常基本的,因此如果您有JSON数组,则可以将其反序列化为列表,例如,如果它是目标类型。自动字符串到int转换也是如此(反之亦然)。是否可以配置反序列化程序,以便在类型不完全匹配时引发错误?是否要检测不具有预期类型的
id
s?如果是,可以将其反序列化为动态(检查Maksim的解决方案)并检查类型:
JsonConvert.DeserializeObject(jsonStr).id.Type
非常棒的答案,应该是公认的答案。这是我唯一能看到的定制特定情况下可能发生的特殊异常情况的方法。
var settings = new JsonSerializerSettings
{
    Converters = { new StrictIntConverter() },
};
var root = JsonConvert.DeserializeObject<RootObject>(json, settings);