JSON.Stringify对物体的Scripting.Dictionary失败 [英] JSON.Stringify fails on Scripting.Dictionary objects

查看:214
本文介绍了JSON.Stringify对物体的Scripting.Dictionary失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个ASP经典的项目,我已经实现了发现的JScript JSON类<一href=\"https://github.com/nagaozen/asp-xtreme-evolution/blob/master/lib/axe/classes/Parsers/json2.asp\"相对=nofollow>此处。它能够与两个VBScript和JScript到互操作,并几乎完全在 json.org <提供的code / A>。我需要使用VBScript为这个项目由我的团队的经理。

I am working on an ASP classic project where I have implemented the JScript JSON class found here. It is able to interop with both VBScript and JScript and is almost exactly the code provided at json.org. I am required to use VBScript for this project by the manager of my team.

它工作得非常好于内ASP定义原语和类。但我需要解释的对象从我的知识只能通过COM互操作。 (通过的Server.CreateObject(的Scripting.Dictionary))我有重新$ P $以下类psents产品:(ProductInfo.class.asp)

It works very well on primitives and classes defined within ASP. But I have need for Dictionary objects which from my knowledge are only available through COM interop. (via Server.CreateObject("Scripting.Dictionary")) I have the following class which represents a product: (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
%>

规格属性是关键的解释:值对。下面是我如何序列化它:(product.asp)

The Specs property is a Dictionary of key:value pairs. Here's how I'm serializing it: (product.asp)

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

当我路过产品介绍的实例 JSON.Stringify (如上所示)我得到的东西像以下内容:

When I pass an instance of ProductInfo to JSON.Stringify (as seen above) I get something like the following:

{
    "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": {}
}

正如你所看到的,规格属性是一个空的对象。我相信,JSON字符串化方法知道了规格属性是一个对象,因此它追加 {} 来的JSON字符串周围的字符串化的输出。在这种情况下是空字符串。我希望它来展示,但不是一个空洞的对象。见下图:

As you can see, the Specs property is an empty object. I believe that the JSON stringify method knows that the Specs property is an object, so it appends the {} to the JSON string around the stringified output. Which in this case is an empty string. What I expect it to show, however is not an empty object. See below:

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

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

I believe the problem area of the JSON library is here: (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);
        }
    }
}

我假设,上述code中的问题是,它假定所有的物体从对象类继承。 (一个提供有一个的hasOwnProperty ),但我认为这很可能是COM对象不从对象类继承&MDASH;或至少​​的相同对象类。或者至少没有实现任何接口,需要做的为中... 在他们身上。

I postulate that the problem with the above code is that it assumes that all objects inherit from the Object class. (The one that provides hasOwnProperty) However I think that it's likely that COM objects don't inherit from the Object class — or at least the same Object class. Or at least don't implement whatever interface is required to do for ... in on them.

更新:虽然我觉得这是不相关的问题回答&MDASH;我期待某种Web客户端来请求(通过HTTP)此对象的JSON重新presentation或此对象的集合。

Update: While I feel it is irrelevant for the question to be answered — I expect some sort of web client to request (via http) the JSON representation of this object or a collection of this object.

TL;博士的问题:我应该怎么做才能让这个在的Scripting.Dictionary 可以正确输出为JSON,而不是失败,只返回一个空字符串?我是否需要推倒重来,写在VBScript我自己的词典确实的行为在ASP正常的对象?

tl;dr The question: What should I do to make it so that the Scripting.Dictionary can be output properly as JSON instead of failing and returning just an empty string? Do I need to 'reinvent the wheel' and write my own Dictionary class in VBScript that does act as a normal object in ASP?

推荐答案

JavaScript的为中... 结构(这是在你指的是JSON序列化使用)仅适用于本地JS对象。枚举的的Scripting.Dictionary 键,您需要使用的枚举对象,这将枚举字典的键。

Javascript’s for...in construct (which is used in the JSON serializer you refer to) only works on native JS objects. To enumerate a Scripting.Dictionary’s keys, you need to use an Enumerator object, which will enumerate the keys of the Dictionary.

现在的 JSON.stringify 方法具有可自定义的序列,通过检查一个的toJSON 每个属性方法。不幸的是,你不能钉新方法对现有的COM对象的方式,你可以在本机的JS对象,所以这是一个不走。

Now the JSON.stringify method has a nifty way of allowing custom serialization, by checking for the presence of a toJSON method on each property. Unfortunately, you can’t tack new methods on existing COM objects the way you can on native JS objects, so that’s a no-go.

再有就是可以作为第二个参数字符串化方法调用传递自定义功能stringifier。该函数将被要求需要被字符串化,甚至每一个嵌套对象中的每个对象。我认为,可以在这里使用。

Then there’s the custom stringifier function that can be passed as second argument to the stringify method call. That function will be called for each object that needs to be stringified, even for each nested object. I think that could be used here.

的一个问题是(AFAIK)JScript是无法区分自身的VBScript类型。为JScript,任何COM或VBScript对象的typeof ===对象。我知道对面获得该信息的唯一途径,是定义一个VBS函数将返回类型名称。

One problem is that (AFAIK) JScript is unable to differentiate VBScript types on its own. To JScript, any COM or VBScript object has typeof === 'object'. The only way I know of getting that information across, is defining a VBS function that will return the type name.

由于传统的ASP文件的执行顺序如下:

Since the execution order for classic ASP files is as follows:


  • &LT;脚本&gt;在非默认脚本语言编写块(在你的情况,JScript中)

  • &LT;脚本&gt;在默认脚本语言块(在你的情况,VBScript中)

  • &LT;%...%GT; 块,将使用默认脚本语言(在你的情况,VBScript中)

  • <script> blocks with non-default script languages (in your case, JScript)
  • <script> blocks with the default script language (in your case, VBScript)
  • <% ... %> blocks, using the default script language (in your case, VBScript)

以下可以工作 - 但的只有的当 JSON.stringify 通话中&LT进行;%.. %&GT; 括号,因为这是唯一一次当两个JScript和VBScript &LT;脚本方式&gt; 部分将都被解析并执行

The following could work — but only when the JSON.stringify call is done within <% ... %> brackets, since that’s the only time when both JScript and VBScript <script> sections would both have been parsed and executed.

最后一个函数调用会是这样:

The final function call would be this:

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

为了让JScript中来检查COM对象的类型,我们就定义了一个VBSTypeName功能:

In order to allow JScript to check the type of a COM object, we'd define a VBSTypeName function:

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

在这里,我们有充分的实现,沿作为第二个参数传递给JSON.stringify的vbsStringifier的:

And here we have the full implementation of the vbsStringifier that is passed along as second parameter to 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功能),所以你可能想尽量保留到最低限度。

Of course, switching back and forth between scripting engines isn’t very efficient (i.e. calling a VBS function from JS and vice versa), so you probably want to try to keep that to a minimum.

另外请注意,我一直没能对此进行测试,因为我不再有IIS我的机器上。基本原则应该工作,我不是100%肯定的传递从VBScript一个JScript函数引用的可能性。您可能需要写一个小的自定义包装函数在JScript中的JSON.stringify电话:

Also note that I haven’t been able to test this, since I no longer have IIS on my machine. The basic principle should work, I’m not 100% certain of the possibility to pass a JScript function reference from VBScript. You might have to write a small custom wrapper function for the JSON.stringify call in JScript:

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

之后,你可以简单地调整VBScript中调用:

after which you can simply adjust the VBScript call:

<%
    Response.Write JSONStringify(oProd)
%>

这篇关于JSON.Stringify对物体的Scripting.Dictionary失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆