JSON.Stringify 在 Scripting.Dictionary 对象上失败

2023-12-06

我正在开发一个 ASP 经典项目,在该项目中我实现了 JScript JSON 类here。它能够与 VBScript 和 JScript 互操作,并且几乎与以下位置提供的代码完全相同:json.org。我的团队经理要求我在这个项目中使用 VBScript。

它非常适用于 ASP 中定义的基元和类。但我需要 Dictionary 对象,据我所知,这些对象只能通过 COM 互操作获得。 (通过Server.CreateObject("Scripting.Dictionary"))我有以下代表产品的类:(ProductInfo.class.asp)

<%
Class ProductInfo

    Public ID
    Public Category
    Public PriceUS
    Public PriceCA
    Public Name
    Public SKU
    Public Overview
    Public Features
    Public Specs

End Class
%>

The Specs属性是键:值对的字典。这是我对其进行序列化的方式:(product.asp)

<%
dim oProd
set oProd = new ProductInfo
' ... fill in properties
' ... output appropriate headers and stuff
Response.write( JSON.stringify( oProd ) )
%>

当我传递一个实例时ProductInfo to JSON.Stringify(如上所示)我得到类似以下内容:

{
    "id": "1547",
    "Category": {
        "id": 101,
        "Name": "Category Name",
        "AlternateName": "",
        "URL": "/category_name/",
        "ParentCategoryID": 21
    },
    "PriceUS": 9.99,
    "PriceCA": 11.99,
    "Name": "Product Name",
    "SKU": 3454536,
    "Overview": "Lorem Ipsum dolor sit amet..",
    "Features": "Lorem Ipsum dolor sit amet..",
    "Specs": {}
}

如您所见,Specs属性是一个空对象。我相信 JSON stringify 方法知道Specs属性是一个对象,因此它附加了{}到周围的 JSON 字符串字符串化的输出。在本例中是一个空字符串。然而,我期望它显示的并不是一个空物体。见下文:

"Specs": {
    "foo":"bar",
    "baz":1,
    "etc":"..."
}

我相信 JSON 库的问题区域在这里:(json2.asp)

// Otherwise, iterate through all of the keys in the object.

for (k in value) {
    if (Object.hasOwnProperty.call(value, k)) {
        v = str(k, value);
        if (v) {
            partial.push(quote(k) + (gap ? ': ' : ':') + v);
        }
    }
}

我假设上面代码的问题在于它假设所有对象都继承自Object班级。 (提供的那个hasOwnProperty)但是我认为 COM 对象很可能不会继承自Object类——或者至少是same Object班级。或者至少不要实现任何需要执行的接口for ... in在他们。

Update:虽然我觉得这与要回答的问题无关——我希望某种 Web 客户端请求(通过 http)该对象的 JSON 表示形式或该对象的集合。

tl;博士 问题:我应该做什么才能使Scripting.Dictionary可以正确输出为 JSON,而不是失败并仅返回空字符串?我需要“重新发明轮子”并编写自己的吗DictionaryVBScript 中的类does充当 ASP 中的普通对象?


JavaScript 的for...in构造(在您引用的 JSON 序列化器中使用)仅适用于本机 JS 对象。枚举一个Scripting.Dictionary的键,您需要使用枚举器对象,它将枚举字典的键。

Now the JSON.stringify方法有一种允许自定义序列化的巧妙方法,通过检查是否存在toJSON每个属性的方法。不幸的是,您无法像在本机 JS 对象上那样在现有 COM 对象上添加新方法,因此这是不行的。

然后是自定义字符串生成器函数,可以作为第二个参数传递给stringify方法调用。将为每个需要字符串化的对象(甚至每个嵌套对象)调用该函数。我认为这可以用在这里。

一个问题是(据我所知)JScript 无法自行区分 VBScript 类型。对于 JScript,任何 COM 或 VBScript 对象都具有typeof === 'object'。我知道获取该信息的唯一方法是定义一个返回类型名称的 VBS 函数。

由于经典ASP文件的执行顺序如下:

  • <script>使用非默认脚本语言的块(在您的情况下为 JScript)
  • <script>使用默认脚本语言的块(在您的情况下为 VBScript)
  • <% ... %>块,使用默认脚本语言(在您的情况下,VBScript)

以下方法可能有效——但是only当。。。的时候JSON.stringify呼叫在以下时间内完成<% ... %>括号,因为这是 JScript 和 VBScript 唯一一次<script>部分都将被解析并执行。

最终的函数调用将是这样的:

<%
    Response.Write JSON.stringify(oProd, vbsStringifier)
%>

为了允许 JScript 检查 COM 对象的类型,我们定义一个 VBSTypeName 函数:

<script language="VBScript" runat="server">
    Function VBSTypeName(Obj)
        VBSTypeName = TypeName(Obj)
    End Function
</script>

这里我们有 vbsStringifier 的完整实现,它作为第二个参数传递给 JSON.stringify:

<script language="JScript" runat="server">

    function vbsStringifier(holder, key, value) {
        if (VBSTypeName(value) === 'Dictionary') {
            var result = '{';
            for(var enr = new Enumerator(value); !enr.atEnd(); enr.moveNext()) {
                key = enr.item();
                result += '"' + key + '": ' + JSON.stringify(value.Item(key));
            }
            result += '}';
            return result;
        } else {
        // return the value to let it be processed in the usual way
            return value;
        }
    }

</script>

当然,在脚本引擎之间来回切换并不是很有效(即从 JS 调用 VBS 函数,反之亦然),因此您可能希望尝试将其保持在最低限度。


另请注意,我无法对此进行测试,因为我的计算机上不再有 IIS。基本原理应该可行,我不能 100% 确定从 VBScript 传递 JScript 函数引用的可能性。您可能需要为 JScript 中的 JSON.stringify 调用编写一个小的自定义包装函数:

<script runat="server" language="JScript">
    function JSONStringify(object) {
        return JSON.stringify(object, vbsStringifier);
    }
</script>

之后您可以简单地调整 VBScript 调用:

<%
    Response.Write JSONStringify(oProd)
%>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSON.Stringify 在 Scripting.Dictionary 对象上失败 的相关文章

随机推荐

  • 如何从基本控制器中的 OnActionExecuting 重定向?

    我尝试了两种方法 Response Redirect 不执行任何操作 以及调用基本控制器内部的新方法返回 ActionResult 并让它返回 RedirectToAction 这些都不起作用 如何从 OnActionExecuting 方
  • 如何修复“无法加载 TClassName 的单元 UnitName 符号信息。您想尝试自己查找此文件吗?”

    在delphi 中 创建ActiveX 控件曾经比现在更流行 然而 仍然可以使用 Delphi 创建 ActiveX 控件 这个问题假设Delphi 2007 但无论你使用什么Delphi版本 它都应该是相同的 当您创建 ActiveX 控
  • 移动文本模式光标不起作用

    我一直致力于在我目前正在开发的操作系统中移动文本模式光标 我根本无法让它显示出来 这是我用来更新光标的代码 void update cursor unsigned char cursor loc y pos Cols x pos curso
  • 如何确定给定 wxWidgets 中当前字体的字符串的大小

    有没有办法根据 C wxWidgets中当前选择的字体确定给定字符串的显示长度 以像素为单位 例如 如果我打印出字符串 Speed 并希望在 和后面的值之间放置 10 个像素 我需要知道 Speed 字符串有多长 有没有办法确定这一点 我似
  • 带有 Spark 流的多个 writeStream

    我正在使用 Spark Streaming 在尝试实现多个写入流时遇到一些问题 下面是我的代码 DataWriter writeStreamer firstTableData parquet CheckPointConf firstChec
  • Scala 注释实际上是什么? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我不懂Java 开始学习Scala 什么是注释以及它们的用途是什么 注释是附加到类 方法
  • 将 url 参数传递给 swf (flash) 影片

    这里是Flash新手 我正在尝试在浏览器中加载 swf 文件并将 url 参数传递给 flash 影片 如何在actionscript中访问flash电影中的url参数 这是一个示例网址 我确实找到了通过嵌入 对象标签传递参数的指针 但没有
  • MockMvc WebAppConfiguration:在 web.xml 中加载 servlet 映射

    我正在使用 MockMvc 编写集成测试 我想知道是否有一种方法可以从 web xml 加载 servlet 映射 这通常不重要 我有一个习惯HandlerInteceptor与请求 URI 匹配 来自HttpServletRequest
  • Trac,如何分层组织页面?

    I use trac管理我的项目 我想以与 trac 项目相同的方式组织 wiki 页面 即按类别 子类别等 标题索引trac 网站上的页面很好地解释了我想要获得的结果 我该如何实现这一目标 首先 你可以创建分层的wiki页面 只需修改ur
  • 有没有办法改变 UIToolbar 的高度?

    我有一个UIToolbar在 Interface Builder 中 我注意到它的高度被锁定为 44px 当然 我想把它做得更大 Apple 允许调整此控件的大小吗 如果是这样 我该怎么办 当然 只需将其框架设置不同即可 myToolbar
  • python 日志记录 - 使用 JSON 日志,我可以为每个日志添加“额外”值吗?

    我正在使用蟒蛇logging模块 以及python json logger我想添加一些键 app name myapp env prod 自动查看我的所有日 志 无需执行以下操作 logger info Something happened
  • 为什么当我设置元素位置:绝对时线性渐变消失?

    我制作了一个渐变背景 我想将这个文本块居中 我的目标是创建一个位于屏幕中间中心的标题 无论视口的分辨率如何 所以我把这个 header 设置为绝对位置 并使用了我在网上找到的这种集中方法 它完美地集中 问题是 渐变背景变成白色 看起来标题位
  • 查找开放会话数

    我正在寻找一种简单 无数据库 的方法来列出网站上有多少活跃用户 我能想到的最简单的方法是计算打开会话的数量 这段代码应该管用 number of users count scandir ini get session save path 当
  • std regex_search 仅匹配当前行

    我使用各种正则表达式逐行解析 C 源文件 首先我读取字符串中文件的所有内容 ifstream file stream commented cpp ifstream binary std string txt std istreambuf i
  • 如何将参数注入 TestCafé 测试?

    设想 我使用 API 运行用代码封装的 TestCaf 我有一个想要参数化的测试 使用不同的动态值进行测试 Problem Testcaf 不支持向测试发送参数 有没有办法注入值 您可以使用进程 env将参数从运行程序脚本传递给 TestC
  • 如何从 Guava MultiMap 中获取每个条目及其关联的相应值?

    我正在读取一个巨大的 csv 文件 其中包含重复的条目 我能够将整个 csv 文件读入Multimap 我还能够获取具有重复值的键集并将它们写入文件 我想获取与每个键关联的值并将其写入文件 但无法这样做 我似乎找不到任何可能对我有帮助的选项
  • 如何在 Rails 4 中将 PDF 转换为 Excel 或 CSV

    我已经搜索了很多 除非在这里问这个问题 否则我别无选择 你们知道有一个在线转换器有 API 或 Gem s 可以将 PDF 转换为 Excel 或 CSV 文件吗 我也不确定这里是否是问这个问题的最佳地点 我的应用程序是在 Rails 4
  • 有没有办法使用命令行 cURL 跟踪重定向?

    我知道在 php 脚本中 curl setopt ch CURLOPT FOLLOWLOCATION true 将遵循重定向 有没有办法使用命令行 cURL 跟踪重定向 使用位置标头标志 curl L
  • 为什么 re.sub('.*?', '-', 'abc') 返回 '-a-b-c-' 而不是 '--------'?

    这是python2 7的结果 gt gt gt re sub abc a b c 我以为的结果should如下 gt gt gt re sub abc 但事实并非如此 为什么 据我所知 对这种行为的最好解释来自regexPyPI 包 其目的
  • JSON.Stringify 在 Scripting.Dictionary 对象上失败

    我正在开发一个 ASP 经典项目 在该项目中我实现了 JScript JSON 类here 它能够与 VBScript 和 JScript 互操作 并且几乎与以下位置提供的代码完全相同 json org 我的团队经理要求我在这个项目中使用