2

我正在使用 jQuery 和其他一些工具使用 ajax 进行应用程序,并且在某些部分我想使用经典的 ASP 后端使用 ajax 检索数据,我看到在 AX 中存在 JSON 类的良好实现(Asp 极端版)框架,我使用它,但目前我不明白如何很好地使用它。

编辑:基于JSON.Stringify 在 Scripting.Dictionary 对象线程上失败的正确答案,我决定制作一个自定义函数来处理 Recordsets。

编辑 2:现在我在函数 JSONStringify(object)中调用JSON.stringify时丢失了值数据。

当记录集作为值传递给JSONStringify时,一切正常,但是当执行JSON.stringify时,必须包含记录集的“值”参数变为未定义

我期待什么(示例)

从 SQL 查询中传递 RecordsetSELECT name, tel FROM users看到这样的输出

[
    {"name":"Jonh Smith", "tel":"12345678"},
    {"name":"April Michelson", "tel":"77788802"},
    ...
]

传递字典并根据字典中声明的元素查看类似的内容。

{
   "element1":"value1",
   "element2":"value2",
   "element3":"value3",
   "element4":"value4",
   "element5":"value5"
}

如果我喜欢支持其他类型的对象,我可以扩展功能

源代码

获取目录.asp

<!--#include file="../includes/conexion.asp" -->
<!--#include file="../includes/json2.asp" -->
<!--#include file="../includes/json-stringify-parser.asp" -->
<%
Response.ContentType = "application/json"
dim aVals(2)

function getCatalogo(tipo, params)
    Dim oConn,oCmd,sSQL,oRs,cont2
    Dim aData,oPar,cont
    dim Info 

    set oConn = Server.CreateObject("ADODB.Connection")
    set oCmd = Server.CreateObject("ADODB.Command")

    sWhere = ""

    oConn.ConnectionString = strcon
    oConn.Open
    Set oCmd.ActiveConnection = oConn

    select case tipo
        case "g"
            sSQL = " SELECT cve_gr, descr FROM gr ORDER BY descr ;"
        case "z" 
            sSQL = " SELECT cve_zn, descr FROM zn WHERE cve_gr = ? ORDER BY descr ;"
            if IsArray(params) Then
                Set oPar=oCmd.CreateParameter (params(0),129,1,2,params(1))
                oCmd.Parameters.Append(oPar)
            End if
        case else
            getCatalogo = false
            exit function
    end select

    oCmd.CommandText = sSQL
    Set oRs = oCmd.Execute()
    if Not oRs.EOF Then
        response.write(JSONStringify(oRs))
        getCatalogo = true
    else
        getCatalogo = false
    end if
    oConn.Close
end function

aVals(0) = "cve_gr"
aVals(1) = request.querystring("gr")
if Not getCatalogo(request.querystring("t"),aVals) Then
    %>error<%
end if

%>

json-stringify-parser.asp

<!--#include file="vbsTyper.asp" -->
<script runat="server" language="JScript">

    function JSONStringify(object) {
        VBSTypeName(object);
        return JSON.stringify(object,stringifyData);
    }

    function stringifyData(holder, key, value) {
        var sType = '';
        var result;

        //response.write('pre...holder=' + holder + ',key=' + key + ',value=' + value);
        sType = VBSTypeName(value);
        //response.write('post =' + sType);

        //response.write(sType);
        switch(sType){
            case 'Dictionary':
                result = '{';
                for(var enr = new Enumerator(value); !enr.atEnd(); enr.moveNext()){
                    key = enr.item();
                    result += '"' + key + '": ' + JSON.stringify(value.Item(key));
                };
                result += '}';
                return(result);
                break;
            case 'Recordset':
                response.write('here!!!');
                var sTemp = '';
                result = '{';
                while(!value.EOF){
                    if(Len(result) > 0){
                        result += ',';
                    }
                    result += '{';
                    for (var i = value.Fields.Count - 1; i >= 0; i--){
                        if(len(sTemp) > 0){
                            sTemp += ',';
                        }
                        sTemp += '"' + value.Fields(i).name + '":' + JSON.stringify( value.Fields(i).value);
                    };
                    result += '}';
                }   
                result += '}';
                return result;
                break;
            default:
                //response.write(sType);
                return(value);
        }     
        // return the value to let it be processed in the usual way
        return result;
   }

</script>

vbsTyper.asp

<%
Function VBSTypeName(Obj)
    dim sType 
    sType = Cstr(TypeName(Obj))
    response.write(sType)
    VBSTypeName = sType
End Function
%>
4

2 回答 2

2

这:

response.write(JSON.stringify(oRs))

应该是这样的:

Do Until oRS.EOF
  response.write(JSON.stringify(oRs("cve_gr") & ":" & oRs("descr"))
  oRS.MoveNext
Loop
于 2012-02-17T20:05:43.510 回答
1

有点实现它...

简短版本:我不得不修改 json2.asp 并破解 stringify() 函数定义以使其工作。

长版

后来看到每一行代码并放弃了这个问题。我决定看看json2.asp(AXE 框架)并尝试看看它在那里发生了什么。

看看我所看到的:

json2.asp源代码截图

从第 682 行到第 687 行,如果找到自定义字符串解析器但后来不执行任何操作,则进行验证...仅返回 Object 值。

这里有猜测,因为我不太了解每个 Javascript 实现是如何工作的,但暗示原始代码运行良好,一个标准的 javascript 解释器(在此处阅读除 microsoft 之外的所有内容)将强制在这种情况下对对象进行序列化,但 JScript 解释器尝试解析对象并将值作为null传递。导致每个使用自定义 stringyfier 的函数都无法读取函数中传递的对象。

我做了什么来解决好的,我在第 688 行之前插入了这段代码,强制执行自定义 stringyfier,其值直接作为参数传递,避免了隐式解析。

        // Hack & patch to deliver the stringify-ing of the object correctly
        // IDK if this is CORRECT or dont but it works in VbScript
        if(replacer){
            var textval = rep(this,'',value);
            value = textval;
        }

后来我不得不在json-stringify-parser.asp中做一些更改,因为我必须修复一些导致此代码的错误

<!--#include file="vbsTyper.asp" -->
<script runat="server" language="JScript">

    function JSONStringify(object) {
        //VBSTypeName(object);
        return JSON.stringify(object,stringifyData,4);
    }

    function stringifyData(holder, key, value) {
        var sType = '';
        var result;

        //response.write('pre...holder=' + holder + ',key=' + key + ',value=' + value);
        sType = VBSTypeName(value);
        //response.write('post =' + sType);

        //response.write(sType);
        switch(sType){
            case 'Dictionary':
                result = '{';
                for(var enr = new Enumerator(value); !enr.atEnd(); enr.moveNext()){
                    key = enr.item();
                    result += '"' + key + '": ' + JSON.stringify(value.Item(key));
                };
                result += '}';
                return(result);
                break;
            case 'Recordset':
                //response.write('here!!!');
                var sTemp;
                result = '';
                while(!value.EOF){
                    if(result.length > 0){
                        result += ',';
                    }
                    result += '{';
                    sTemp=''
                    for (var i = 0; i < value.fields.Count; i++){
                        if(sTemp.length > 0){
                            sTemp += ',';
                        }
                        //response.write("i=" + i + ",");
                        sTemp += '"' + value.fields.item(i).name + '":' + JSON.stringify( value.fields.item(i).value);
                    };
                    result += sTemp + '}';
                    value.moveNext();
                }   
                result = '{' + result  + '}';
                return result;
                break;
            default:
                //response.write(sType);
                return(value);
        }     
        // return the value to let it be processed in the usual way
        return result;
   }

</script>

解析 Recordset 的部分有效,解析字典的部分与JSON.Stringify中所示的相同,Scripting.Dictionary 对象失败(也就是我还没有测试过),但现在我已经完成了。

使用记录集对象测试我的更改会产生此输出

"{
    {\"clave\":\"BC\",\"descripcion\":\"Cal\"},
    {\"clave\":\"CT\",\"descripcion\":\"Center\"},
    {\"clave\":\"NE\",\"descripcion\":\"Norw\"},
    {\"clave\":\"NO\",\"descripcion\":\"Nore\"},
    {\"clave\":\"NT\",\"descripcion\":\"North\"},
    {\"clave\":\"OC\",\"descripcion\":\"East\"},
    {\"clave\":\"OR\",\"descripcion\":\"West\"},
    {\"clave\":\"PE\",\"descripcion\":\"Pen\"},
    {\"clave\":\"SE\",\"descripcion\":\"Southe\"},
    {\"clave\":\"ZM\",\"descripcion\":\"Met\"}
}"

剩下的问题

我留下的问题有点像黑客。

  • 没关系,输出在开头和结尾都有 (") 字符,而我其他所有内容都有转义 ?? 或者这是不应该发生的事情。

  • 这种黑客行为真的是错误的......在这种情况下我可以做得更好吗?

  • 我的结论或论点有问题??

于 2012-02-22T19:38:46.493 回答