json.asp代码:
<% '********************************************************************************************** '* GAB_LIBRARY Copyright (C) 2003 - This file is part of GAB_LIBRARY '* For license refer to the license.txt '*********************************************************************************************** '**************************************************************************************** '' @CLASSTITLE: JSON '' @CREATOR: Michal Gabrukiewicz (gabru at grafix.at), Michael Rebec '' @CONTRIBUTORS: - Cliff Pruitt (opensource at crayoncowboy.com) '' - Sylvain Lafontaine '' @CREATEDON: 2007-04-26 12:46 '' @CDESCRIPTION: Comes up with functionality for JSON (http://json.org) to use within ASP. '' Correct escaping of characters, generating JSON Grammer out of ASP datatypes and structures '' @REQUIRES: - '' @OPTIONEXPLICIT: yes '' @VERSION: 1.4 '**************************************************************************************** class JSON 'private members private output, innerCall 'public members public toResponse ''[bool] should generated results be directly written to the response? default = false '********************************************************************************* '* constructor '********************************************************************************* public sub class_initialize() newGeneration() toResponse = false end sub '****************************************************************************************** '' @SDESCRIPTION: STATIC! takes a given string and makes it JSON valid '' @DESCRIPTION: all characters which needs to be escaped are beeing replaced by their '' unicode representation according to the '' RFC4627#2.5 - http://www.ietf.org/rfc/rfc4627.txt?number=4627 '' @PARAM: val [string]: value which should be escaped '' @RETURN: [string] JSON valid string '' asc 函数被替换成ascw函数以便支持中文 '****************************************************************************************** public function escape(val) dim cDoubleQuote, cRevSolidus, cSolidus cDoubleQuote = &h22 cRevSolidus = &h5C cSolidus = &h2F dim i, currentDigit for i = 1 to (len(val)) currentDigit = mid(val, i, 1) if ascw(currentDigit) > &h00 and ascw(currentDigit) < &h1F then currentDigit = escapequence(currentDigit) elseif ascw(currentDigit) >= &hC280 and ascw(currentDigit) <= &hC2BF then currentDigit = "\u00" + right(padLeft(hex(asc(currentDigit) - &hC200), 2, 0), 2) elseif ascw(currentDigit) >= &hC380 and ascw(currentDigit) <= &hC3BF then currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC2C0), 2, 0), 2) else select case ascw(currentDigit) case cDoubleQuote: currentDigit = escapequence(currentDigit) case cRevSolidus: currentDigit = escapequence(currentDigit) case cSolidus: currentDigit = escapequence(currentDigit) end select end if escape = escape & currentDigit next end function '****************************************************************************** '' @SDESCRIPTION: generates a representation of a name value pair in JSON grammer '' @DESCRIPTION: the generation is done fully recursive so the value can be a complex datatype as well. e.g. '' toJSON("n", array(array(), 2, true), false) or toJSON("n", array(RS, dict, false), false), etc. '' @PARAM: name [string]: name of the value (accessible with javascript afterwards). leave empty to get just the value '' @PARAM: val [variant], [int], [float], [array], [object], [dictionary], [recordset]: value which needs '' to be generated. Conversation of the data types (ASP datatype -> Javascript datatype): '' NOTHING, NULL -> null, ARRAY -> array, BOOL -> bool, OBJECT -> name of the type, '' MULTIDIMENSIONAL ARRAY -> generates a 1 dimensional array (flat) with all values of the multidim array '' DICTIONARY -> valuepairs. each key is accessible as property afterwards '' RECORDSET -> array where each row of the recordset represents a field in the array. '' fields have properties named after the column names of the recordset (LOWERCASED!) '' e.g. generate(RS) can be used afterwards r[0].ID '' INT, FLOAT -> number '' OBJECT with reflect() method -> returned as object which can be used within JavaScript '' @PARAM: nested [bool]: is the value pair already nested within another? if yes then the {} are left out. '' @RETURN: [string] returns a JSON representation of the given name value pair '' (if toResponse is on then the return is written directly to the response and nothing is returned) '******************************************************************************************* public function toJSON(name, val, nested) if not nested and not isEmpty(name) then write("{") if not isEmpty(name) then write("""" & escape(name) & """: ") generateValue(val) if not nested and not isEmpty(name) then write("}") toJSON = output if innerCall = 0 then newGeneration() end function '********************************************************************************* '* generate '****************************************************************************** private function generateValue(val) if isNull(val) then write("null") elseif isArray(val) then generateArray(val) elseif isObject(val) then if val is nothing then write("null") elseif typename(val) = "Dictionary" then generateDictionary(val) elseif typename(val) = "Recordset" then generateRecordset(val) else generateObject(val) end if else 'bool varTyp = varType(val) if varTyp = 11 then if val then write("true") else write("false") 'int, long, byte elseif varTyp = 2 or varTyp = 3 or varTyp = 17 or varTyp = 19 then write(cLng(val)) 'single, double, currency elseif varTyp = 4 or varTyp = 5 or varTyp = 6 or varTyp = 14 then write(replace(cDbl(val), ",", ".")) else write("""" & escape(val & "") & """") end if end if generateValue = output end function '***************************************************************************** '* generateArray '***************************************************************************** private sub generateArray(val) dim item, i write("[") i = 0 'the for each allows us to support also multi dimensional arrays for each item in val if i > 0 then write(",") generateValue(item) i = i + 1 next write("]") end sub '********************************************************************************* '* generateDictionary '************************************************************************** private sub generateDictionary(val) dim keys, i innerCall = innerCall + 1 write("{") keys = val.keys for i = 0 to uBound(keys) if i > 0 then write(",") toJSON keys(i), val(keys(i)), true next write("}") innerCall = innerCall - 1 end sub '******************************************************************* '* generateRecordset '******************************************************************* private sub generateRecordset(val) dim i write("[") while not val.eof innerCall = innerCall + 1 write("{") for i = 0 to val.fields.count - 1 if i > 0 then write(",") toJSON lCase(val.fields(i).name), val.fields(i).value, true next write("}") val.movenext() if not val.eof then write(",") innerCall = innerCall - 1 wend write("]") end sub '******************************************************************************* '* generateObject '******************************************************************************* private sub generateObject(val) dim props on error resume next set props = val.reflect() if err = 0 then on error goto 0 innerCall = innerCall + 1 toJSON empty, props, true innerCall = innerCall - 1 else on error goto 0 write("""" & escape(typename(val)) & """") end if end sub '******************************************************************************* '* newGeneration '******************************************************************************* private sub newGeneration() output = empty innerCall = 0 end sub '******************************************************************************* '* JsonEscapeSquence '******************************************************************************* private function escapequence(digit) escapequence = "\u00" + right(padLeft(hex(asc(digit)), 2, 0), 2) end function '***************************************************************************** '* padLeft '***************************************************************************** private function padLeft(value, totalLength, paddingChar) padLeft = right(clone(paddingChar, totalLength) & value, totalLength) end function '***************************************************************************** '* clone '****************************************************************************************** public function clone(byVal str, n) dim i for i = 1 to n : clone = clone & str : next end function '****************************************************************************************** '* write '****************************************************************************************** private sub write(val) if toResponse then response.write(val) else output = output & val end if end sub end class %>
dbclass.asp代码:
<% '========================================================================== '文件名称:clsDbCtrl.asp '功 能:数据库操作类 '作 者:coldstone (coldstone[在]qq.com) '程序版本:v1.0.5 '完成时间:2005.09.23 '修改时间:2007.10.30 '版权声明:可以在任意作品中使用本程序代码,但请保留此版权信息。 ' 如果你修改了程序中的代码并得到更好的应用,请发送一份给我,谢谢。 '========================================================================== Dim a : a = CreatConn(0, "shujuku", "localhost", "sa", "123456") 'MSSQL数据库 'Dim a : a = CreatConn(1, "Data/%TestDB%.mdb", "", "", "") 'Access数据库 'Dim a : a = CreatConn(1, "E:\MyWeb\Data\%TestDB%.mdb", "", "", "mdbpassword") Dim Conn 'OpenConn() '在加载时就建立的默认连接对象Conn,默认使用数据库a Sub OpenConn : Set Conn = Oc(a) : End Sub Sub CloseConn : Co(Conn) : End Sub Function Oc(ByVal Connstr) On Error Resume Next Dim objConn Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open Connstr If Err.number <> 0 Then Response.Write("<div id=""DBError"">数据库服务器端连接错误,请与网站管理员联系。</div>") 'Response.Write("错误信息:" & Err.Description) objConn.Close Set objConn = Nothing Response.End End If Set Oc = objConn End Function Sub Co(obj) On Error Resume Next Set obj = Nothing End Sub Function CreatConn(ByVal dbType, ByVal strDB, ByVal strServer, ByVal strUid, ByVal strPwd) Dim TempStr Select Case dbType Case "0","MSSQL" TempStr = "driver={sql server};server="&strServer&";uid="&strUid&";pwd="&strPwd&";database="&strDB Case "1","ACCESS" Dim tDb : If Instr(strDB,":")>0 Then : tDb = strDB : Else : tDb = Server.MapPath(strDB) : End If TempStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&tDb&";Jet OLEDB:Database Password="&strPwd&";" Case "3","MYSQL" TempStr = "Driver={mySQL};Server="&strServer&";Port=3306;Option=131072;Stmt=; Database="&strDB&";Uid="&strUid&";Pwd="&strPwd&";" Case "4","ORACLE" TempStr = "Driver={Microsoft ODBC for Oracle};Server="&strServer&";Uid="&strUid&";Pwd="&strPwd&";" End Select CreatConn = TempStr End Function Class dbCtrl Private debug Private idbConn Private idbErr Private Sub Class_Initialize() debug = true '调试模式是否开启 idbErr = "出现错误:" If IsObject(Conn) Then Set idbConn = Conn End If End Sub Private Sub Class_Terminate() Set idbConn = Nothing If debug And idbErr<>"出现错误:" Then Response.Write(idbErr) End Sub Public Property Let dbConn(pdbConn) If IsObject(pdbConn) Then Set idbConn = pdbConn Else Set idbConn = Conn End If End Property Public Property Get dbErr() dbErr = idbErr End Property Public Property Get Version Version = "ASP Database Ctrl V1.0 By ColdStone" End Property Public Function AutoID(ByVal TableName) On Error Resume Next Dim m_No,Sql, m_FirTempNo Set m_No=Server.CreateObject("adodb.recordset") Sql="SELECT * FROM ["&TableName&"]" m_No.Open Sql,idbConn,3,3 If m_No.EOF Then AutoID=1 Else Do While Not m_No.EOF m_FirTempNo=m_No.Fields(0).Value m_No.MoveNext If m_No.EOF Then AutoID=m_FirTempNo+1 End If Loop End If If Err.number <> 0 Then idbErr = idbErr & "无效的查询条件!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description Response.End() Exit Function End If m_No.close Set m_No = Nothing End Function Public Function GetRecord(ByVal TableName,ByVal FieldsList,ByVal Condition,ByVal OrderField,ByVal ShowN) On Error Resume Next Dim rstRecordList Set rstRecordList=Server.CreateObject("adodb.recordset") With rstRecordList .ActiveConnection = idbConn .CursorType = 3 .LockType = 3 .Source = wGetRecord(TableName,FieldsList,Condition,OrderField,ShowN) .Open If Err.number <> 0 Then idbErr = idbErr & "无效的查询条件!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description .Close Set rstRecordList = Nothing Response.End() Exit Function End If End With Set GetRecord=rstRecordList End Function Public Function wGetRecord(ByVal TableName,ByVal FieldsList,ByVal Condition,ByVal OrderField,ByVal ShowN) Dim strSelect strSelect="select " If ShowN > 0 Then strSelect = strSelect & " top " & ShowN & " " End If If FieldsList<>"" Then strSelect = strSelect & FieldsList Else strSelect = strSelect & " * " End If strSelect = strSelect & " from [" & TableName & "]" If Condition <> "" Then strSelect = strSelect & " where " & ValueToSql(TableName,Condition,1) End If If OrderField <> "" Then strSelect = strSelect & " order by " & OrderField End If wGetRecord = strSelect End Function Public Function GetRecordBySQL(ByVal strSelect) On Error Resume Next Dim rstRecordList Set rstRecordList=Server.CreateObject("adodb.recordset") With rstRecordList .ActiveConnection =idbConn .CursorType = 3 .LockType = 3 .Source = strSelect .Open If Err.number <> 0 Then idbErr = idbErr & "无效的查询条件!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description .Close Set rstRecordList = Nothing Response.End() Exit Function End If End With Set GetRecordBySQL = rstRecordList End Function Public Function GetRecordDetail(ByVal TableName,ByVal Condition) On Error Resume Next Dim rstRecordDetail, strSelect Set rstRecordDetail=Server.CreateObject("adodb.recordset") With rstRecordDetail .ActiveConnection =idbConn strSelect = "select * from [" & TableName & "] where " & ValueToSql(TableName,Condition,1) .CursorType = 3 .LockType = 3 .Source = strSelect .Open If Err.number <> 0 Then idbErr = idbErr & "无效的查询条件!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description .Close Set rstRecordDetail = Nothing Response.End() Exit Function End If End With Set GetRecordDetail=rstRecordDetail End Function Public Function AddRecord(ByVal TableName, ByVal ValueList) On Error Resume Next DoExecute(wAddRecord(TableName,ValueList)) If Err.number <> 0 Then idbErr = idbErr & "写入数据库出错!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description 'DoExecute "ROLLBACK TRAN Tran_Insert" '如果存在添加事务(事务滚回) AddRecord = 0 Exit Function End If AddRecord = AutoID(TableName)-1 End Function Public Function wAddRecord(ByVal TableName, ByVal ValueList) Dim TempSQL, TempFiled, TempValue TempFiled = ValueToSql(TableName,ValueList,2) TempValue = ValueToSql(TableName,ValueList,3) TempSQL = "Insert Into [" & TableName & "] (" & TempFiled & ") Values (" & TempValue & ")" wAddRecord = TempSQL End Function Public Function UpdateRecord(ByVal TableName,ByVal Condition,ByVal ValueList) On Error Resume Next DoExecute(wUpdateRecord(TableName,Condition,ValueList)) If Err.number <> 0 Then idbErr = idbErr & "更新数据库出错!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description 'DoExecute "ROLLBACK TRAN Tran_Update" '如果存在添加事务(事务滚回) UpdateRecord = 0 Exit Function End If UpdateRecord = 1 End Function Public Function wUpdateRecord(ByVal TableName,ByVal Condition,ByVal ValueList) Dim TmpSQL TmpSQL = "Update ["&TableName&"] Set " TmpSQL = TmpSQL & ValueToSql(TableName,ValueList,0) TmpSQL = TmpSQL & " Where " & ValueToSql(TableName,Condition,1) wUpdateRecord = TmpSQL End Function Public Function DeleteRecord(ByVal TableName,ByVal IDFieldName,ByVal IDValues) On Error Resume Next Dim Sql Sql = "Delete From ["&TableName&"] Where ["&IDFieldName&"] In (" If IsArray(IDValues) Then Sql = Sql & "Select ["&IDFieldName&"] From ["&TableName&"] Where " & ValueToSql(TableName,IDValues,1) Else Sql = Sql & IDValues End If Sql = Sql & ")" DoExecute(Sql) If Err.number <> 0 Then idbErr = idbErr & "删除数据出错!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description 'DoExecute "ROLLBACK TRAN Tran_Delete" '如果存在添加事务(事务滚回) DeleteRecord = 0 Exit Function End If DeleteRecord = 1 End Function Public Function wDeleteRecord(ByVal TableName,ByVal IDFieldName,ByVal IDValues) On Error Resume Next Dim Sql Sql = "Delete From ["&TableName&"] Where ["&IDFieldName&"] In (" If IsArray(IDValues) Then Sql = Sql & "Select ["&IDFieldName&"] From ["&TableName&"] Where " & ValueToSql(TableName,IDValues,1) Else Sql = Sql & IDValues End If Sql = Sql & ")" wDeleteRecord = Sql End Function Public Function ReadTable(ByVal TableName,ByVal Condition,ByVal GetFieldNames) On Error Resume Next Dim rstGetValue,Sql,BaseCondition,arrTemp,arrStr,TempStr,i TempStr = "" : arrStr = "" '给出SQL条件语句 BaseCondition = ValueToSql(TableName,Condition,1) '读取数据 Set rstGetValue = Server.CreateObject("ADODB.Recordset") Sql = "Select "&GetFieldNames&" From ["&TableName&"] Where "&BaseCondition rstGetValue.Open Sql,idbConn,3,3 If rstGetValue.RecordCount > 0 Then If Instr(GetFieldNames,",")>0 Then arrTemp = Split(GetFieldNames,",") For i = 0 To Ubound(arrTemp) If i<>0 Then arrStr = arrStr &Chr(112)&Chr(112)&Chr(113) arrStr = arrStr & rstGetValue.Fields(i).Value Next TempStr = Split(arrStr,Chr(112)&Chr(112)&Chr(113)) Else TempStr = rstGetValue.Fields(0).Value End If End If If Err.number <> 0 Then idbErr = idbErr & "获取数据出错!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description rstGetValue.close() Set rstGetValue = Nothing Exit Function End If rstGetValue.close() Set rstGetValue = Nothing ReadTable = TempStr End Function Public Function C(ByVal ObjRs) ObjRs.close() Set ObjRs = Nothing End Function Private Function ValueToSql(ByVal TableName, ByVal ValueList, ByVal sType) Dim StrTemp StrTemp = ValueList If IsArray(ValueList) Then StrTemp = "" Dim rsTemp, CurrentField, CurrentValue, i Set rsTemp = Server.CreateObject("adodb.recordset") With rsTemp .ActiveConnection = idbConn .CursorType = 3 .LockType = 3 .Source ="select * from [" & TableName & "] where 1 = -1" .Open For i = 0 to Ubound(ValueList) CurrentField = Left(ValueList(i),Instr(ValueList(i),":")-1) CurrentValue = Mid(ValueList(i),Instr(ValueList(i),":")+1) If i <> 0 Then Select Case sType Case 1 StrTemp = StrTemp & " And " Case Else StrTemp = StrTemp & ", " End Select End If If sType = 2 Then StrTemp = StrTemp & "[" & CurrentField & "]" Else Select Case .Fields(CurrentField).Type Case 7,133,134,135,8,129,200,201,202,203 If sType = 3 Then StrTemp = StrTemp & "'"&CurrentValue&"'" Else StrTemp = StrTemp & "[" & CurrentField & "] = '"&CurrentValue&"'" End If Case 11 If UCase(cstr(Trim(CurrentValue)))="TRUE" Then If sType = 3 Then StrTemp = StrTemp & "1" Else StrTemp = StrTemp & "[" & CurrentField & "] = 1" End If Else If sType = 3 Then StrTemp = StrTemp & "0" Else StrTemp = StrTemp & "[" & CurrentField & "] = 0" End If End If Case Else If sType = 3 Then StrTemp = StrTemp & CurrentValue Else StrTemp = StrTemp & "[" & CurrentField & "] = " & CurrentValue End If End Select End If Next End With If Err.number <> 0 Then idbErr = idbErr & "生成SQL语句出错!<br />" If debug Then idbErr = idbErr & "错误信息:"& Err.Description rsTemp.close() Set rsTemp = Nothing Exit Function End If rsTemp.Close() Set rsTemp = Nothing End If ValueToSql = StrTemp End Function Private Function DoExecute(ByVal sql) Dim ExecuteCmd Set ExecuteCmd = Server.CreateObject("ADODB.Command") With ExecuteCmd .ActiveConnection = idbConn .CommandText = sql .Execute End With Set ExecuteCmd = Nothing End Function End Class %>
调用示例:
<%@LANGUAGE = "VBSCRIPT" CODEPAGE = "65001" %> <!--#include file="include/dbclass.asp" --> <!--#include file="include/json.asp" --> <% OpenConn() '打开数据库连接 Dim db : Set db = New DbCtrl '建立对象 Co(db) : CloseConn() '释放对象,关闭数据库连接 '示例: dim j '多重嵌套的JSON,要使用Dictionary才能实现 set j = new json j.toResponse = false set r = server.createobject("scripting.dictionary") set b = server.createobject("scripting.dictionary") set c = server.createobject("scripting.dictionary") c.add "x",5 c.add "y",6 c.add "z",11 b.add "event","Mouse Click" b.add "data",c r.add "success", true r.add "result",b a = j.toJSON( empty,r,false) 'response.write a %> <% '-----------------------'读取数据库输出JSON-------------------------- Dim sql_class,sql_top,sql_colums,sql_whereBy,sql_orderBy 'sql_class = request.Item("sql_class") 'sql_top = request.Item("sql_top") 'sql_colums = request.Item("sql_colums") 'sql_whereBy = request.Item("sql_whereBy") 'sql_orderBy = request.Item("sql_orderBy") 'Sql="select "&sql_top&" "&sql_colums&" from "&sql_class&" where 1=1 "&sql_whereBy&" "&sql_orderBy Dim conn2 set conn2 =server.createobject("adodb.connection") Dim connStr connStr = "provider=sqloledb;source=local;uid=sa;pwd=123456;database=shujuku" conn2.Open connStr sql="SELECT top 10 id,username,password,addtime FROM users" Set Rs = Server.CreateObject("ADODB.Recordset") Rs.Open sql,conn2,1,3 jsonStr = "" rows = "" Dim i,json_rows,json_ret,arr_rows Dim myArray() Redim myArray(rs.recordcount-1) '将数组大小重新定义为20 Set jsonObj=New json jsonObj.toResponse=False Set json_ret = server.createobject("scripting.dictionary") For i=0 To rs.recordcount-1 Set myArray(i) = server.createobject("scripting.dictionary") For Each e In rs.Fields 'rows = rows &""""& e.Name & """:""" & replace(e.value,chr(34),"@_'_@") & """," myArray(i).Add e.Name,e.value '将key/value加到行数组对象中 Next Rs.movenext Next json_ret.Add "total",rs.recordcount json_ret.Add "rows",myArray jsonStr = jsonObj.toJSON(Empty,json_ret,False) 'response.Write jsonStr %> <% '记录集转为Json Dim conn3 set conn3 =server.createobject("adodb.connection") Dim connStr3 connStr3 = "provider=sqloledb;source=local;uid=sa;pwd=123456;database=shujuku" conn3.Open connStr3 set i = new json i.toresponse = false set rs = server.CreateObject("adodb.recordset") sqlstr = "select top 5 * from users " rs.open sqlstr,conn3, 0 , 1 v = i.toJson("result",rs,false) rs.close response.write v %>