You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JsonConvert.DeserializeObject遇字符串含NaN时反序列化失败求助

解决Knockout序列化NaN导致后端JsonConvert反序列化失败的问题

这个问题很典型——ko.toJSON会把JavaScript里的NaN值序列化为字符串"NaN",但这不符合JSON官方规范(JSON只允许null、布尔值、数字、字符串、数组和对象这几种类型),而Newtonsoft.Json默认拒绝解析这种非法的JSON值,所以才会出现反序列化失败的情况。下面给你两种可行的解决方案,你可以根据场景选择:

方案一:前端处理(推荐,符合JSON规范)

直接在序列化阶段把NaN替换成合法的null,避免生成不符合规范的JSON。你可以通过以下两种方式实现:

方式1:用原生JSON.stringify代替ko.toJSON

ko.toJSON内部其实依赖JSON.stringify,但它的处理逻辑会保留NaN。你可以先把ViewModel转成普通JavaScript对象(用ko.toJS),再用原生JSON.stringify序列化——原生方法会自动把NaN和Infinity转成null:

// 先转成普通JS对象,再用原生序列化
var plainObj = ko.toJS(viewModel);
var data = JSON.stringify(plainObj);

$.ajax({
    type: 'POST',
    url: '@Url.Action("Action")',
    data: { data: data },
    dataType: 'json'
    // 其他配置...
});

方式2:手动遍历替换NaN

如果需要更精细的控制,可以手动遍历ViewModel对象,把所有NaN值替换成null:

function cleanNaN(obj) {
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            const value = obj[key];
            if (typeof value === 'number' && isNaN(value)) {
                obj[key] = null;
            } else if (typeof value === 'object' && value !== null) {
                cleanNaN(value); // 递归处理嵌套对象
            }
        }
    }
}

var plainObj = ko.toJS(viewModel);
cleanNaN(plainObj);
var data = JSON.stringify(plainObj);

方案二:后端处理(快速解决,但依赖非标准JSON)

如果你不想修改前端代码,可以配置Newtonsoft.Json允许解析NaN值。只需要在反序列化的JsonSerializerSettings中添加AllowNaN = true:

var viewModel = JsonConvert.DeserializeObject<ViewModel>(data, new JsonSerializerSettings 
{ 
    DateTimeZoneHandling = DateTimeZoneHandling.Local, 
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    AllowNaN = true // 允许解析JSON中的NaN值
});

⚠️ 注意:这种方案有个限制——ViewModel中对应的字段必须是double或float类型(因为decimal类型不支持NaN)。如果你的字段是decimal,还是建议用前端方案把NaN转成null,同时把后端字段改成可空的decimal?。

内容的提问来源于stack exchange,提问作者AGuyCalledGerald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:05:34