【问题标题】:Serialise non string values to JSON将非字符串值序列化为 JSON
【发布时间】:2013-02-25 11:50:18
【问题描述】:

我有一个 javascript 对象,其中包括许多整数属性以及日期值和一个整数数组。每当我在对象上调用 JSON.stringify(entityModel, null, 2) 并将结果传递给 HTTP 处理程序时,我都会得到如下结果:

{
 "UserId": "12345",
 "Name": "Stewart",
 "PositionId": "2",
 "NextBirthday": "10-11-2013",
 "FavouriteColour": "Blue",
 "Hobbies": "1,3" // this is an array of ints in the client object prior to stringificaiton
}

当我想要的时候

{
 "UserId": 12345,
 "Name": "Stewart",
 "PositionId": 2,
 "NextBirthday": "10-11-2013",
 "FavouriteColour": "Blue",
 "Hobbies": [1,3]
}

我是 JSON 新手,但有人能告诉我哪里出错了吗?基本上在服务器端,我的反序列化器不会将 Hobbies 属性反序列化为整数数组,并且当它们被 JSON 视为字符串时,整数可能会出现问题。

## 编辑

当页面加载时,我的客户对象是这样的:

function EntityModel(){
   this.UserId = null;
   this.Name = null;
   this.PositionId = null;
   this.NextBirthday = null;
   this.FavouriteColour = null;
   this.Hobbies = null;
}

然后我给它赋值,检查这个值是否是一个数字,并在适当的地方使用 parseInt 赋值一个整数值。对于爱好属性,我分配了一个整数数组,如下所示:

var checkedValues = new Array();
element.find("input[type=checkbox]:checked").each(function () {
   checkedValues.push(parseInt($(this).val()));
});
return checkedValues;  

所以我的对象最终应该看起来像这样

function EntityModel(){
   this.UserId = 123;
   this.Name = "Stewart";
   this.PositionId = 2;
   this.NextBirthday = '10-11-2013';
   this.FavouriteColour = 'blue';
   this.Hobbies = [1,2];
}

然后我将对象传递给处理程序,如下所示:

var json = JSON.stringify(entityModel, null, 2);
$.ajax({
  url: handlerPath,
  contentType: "application/json; charset=utf-8",
  type: 'POST',
  dataType: "json",
  data: json,
  success: OnComplete,
  error: OnFail
});

最后在处理程序端我检索到 JSON 字符串

using (StreamReader inputStream = new StreamReader(      HttpContext.Current.Request.InputStream ))
{
   jsonString = inputStream.ReadToEnd();
}

它看起来像这样

"{\n  \"UserId\": \"12345\",\n  \"Name\": \"Stewart\",\n  \"PositionId\": \"2\",\n  \"NextBirthday\": \"2013-11-10\",\n  \"FavouriteColour\": \"Blue\",\n  \"Hobbies\": \"1,2,3\"\n}"
# 编辑 2

这里是我用来给我的客户对象赋值的函数。第一个函数要么返回一个整数数组(如果值基于复选框列表选择)或一个 int(如果值是一个数字)或一个字符串

function getElemValue(element, elementType, targetType) {
        switch (elementType) {
            case "System.Web.UI.WebControls.CheckBoxList":
                var checkedValues = new Array();
                element.find("input[type=checkbox]:checked").each(function () {
                    checkedValues.push(parseInt($(this).val()));
                });
                return checkedValues;
            default:
                return TryParseInt(element.val());   
        }
    }

    function TryParseInt(str) {
        var retValue = str;
        if (str != null) {
            if (str.length > 0) {
                if (!isNaN(str)) {
                    retValue = parseInt(str);
                }
            }
        }
        return retValue; 
    }

【问题讨论】:

  • 你真的有数组吗?或者你有一些自定义的类似数组的数据结构?
  • 我无法重现它 (jsfiddle.net/FWNRe),这意味着您没有您认为的数字或数组。修复原来的数据结构,得到你想要的JSON。
  • console.log(entityModel) 输出什么?
  • 查看@FelixKling 的评论后,如果您的原始数据结构正确,请检查您没有为 JSON 对象导入写得不好的 shim。
  • 那么在给属性赋值或者对数据进行预处理的时候肯定有问题。但是我们无能为力,因为我们无法运行您的代码。如果您还不了解它,请学习如何使用您的浏览器开发人员工具(看看这个tutorial)来调试 JS 代码。在代码中设置断点并跟踪每个值的创建/处理方式。这通常会很快揭示问题所在。

标签: javascript json serialization


【解决方案1】:

我的印象是,函数 getElementValue 并没有完全按照你的想法做。

以下是我看到的一些(潜在)问题:

  • element 参数是 jQuery 对象吗?如果没有,element.val() 可能会抛出异常。浏览器的控制台是否显示任何错误?
  • 您使用的是parseInt,没有第二个参数(基数);这意味着如果字符串以零 (0) 开头,它将被解释为 八进制 数字。为防止这种情况发生,请使用parseInt(str, 10)(或Number(str),但也可以接受浮点数)。
  • 您的函数TryParseInt 看起来非常复杂。执行parseInt(str, 10) 就足够了,如果产生NaN,则返回原始字符串。

例如:

function tryParseInt(str) {
    var retValue = parseInt(str, 10);
    return isNaN(retValue) ? str : retValue;
}

最后:我在这里看到的只是将一些值分配给 checkedValues 数组,但没有分配给 EntityModel 对象。所以我们仍然错过了最后的任务——我有一种预感,这正是它出错的地方,所有内容都被转换为字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多