Generate JSON from VBScript (ASP) datatypes

By | April 26

When working with JSON it’s nice to have a generator for your language which transforms all the datatypes from your chosen programming language into the JSON grammar so that you can use them within javascript. For a lot of popular languages it’s done already (i suppose) but I haven’t found one for classic ASP .. so here it comes. The following example quickly demonstrates what the goal is:

  1. set RS = getRecordset("SELECT * FROM table")
  2. response.write((new JSON).toJSON("rows", RS))

A simple usage of JSON normally is that you create a page which outputs data as JSON as the only response. This page is called later from another page and the returned data is used within a javascript function (known as callback). So the snippet above gets some data from the database and stores it in an adodb.recordset which is passed then to the JSON generator and the result is printed on the page. The consuming page would like to access the data now as it originally was within the recordset. like this:

function callback(rows) {
for (i = 0; i < rows.length; i++) { alert(rows[i].columName); } } [/javascript] read on to get the details...

If you are already impressed by the short example then you will save a lot of time from now on when working with JSON. I have written a class which handles the whole conversation of classic ASP datatypes to JSON grammar. In particular an ASP boolean is recognized as a boolean within javascript, an integer as a number, an array as an array, a recordset as collection, etc. I will come back to the first example later but first another example:

  1. <script>
  2.    alert(<%= (new JSON).toJSON("foo", array(true, 1, ""), false) %>.foo[0]);
  3. </script>

This short snippet displays an alert with true. As you can see we passed an ASP variable which has been recognized later by javascript. In this very example we even pass an array with 3 different datatypes (boolean, int and string). Those are all accessible within javascript.

Even nesting is fully supported. So array within arrays, dictionaries within arrays and vice versa. Mixing is allowed in every way you imagine. This example demonstrates what i am talking about:

  1. <%
  2. set d = server.createObject("scripting.dictionary")
  3. d.add "en", "sausage"
  4. d.add "de", array("egal", "wurst")
  5. %>
  6. <script>
  7.    alert(<%= (new JSON).toJSON("foo", array(d), false) %>.foo[0].de[1]);
  8. </script>

We’ve created a dictionary (which consists of two value pairs - one holds just a string (sausage) and the other an array (egal, wurst)) and we’ve added this into another array which is the value of “foo”. After toJSON has generated the JSON string we can access the whole structure and the alertbox says “wurst”.

Now back to the example of the introduction. We can even pass whole recordsets to the generator which will generate a datastructure as followed:

JSON representation for ADODB.recordset

a recordset with two columns ID and LASTNAME will be converted into a javascript array where each field represents a row in the field and the row provides properties which are named the same as the columns within the recordset. That means that iterating through data within javascript is not a mission anymore … look at this example:

  1. <script>
  2.    alert(<%= (new JSON).toJSON("data", getRecordset("SELECT id, lastname FROM table"), false) %>.data[0].lastname);
  3. </script>

We transfered the whole adodb.recordset from ASP to javascript using JSON. How cool is that!?

Custom classes

If you create your own classes within VBScript then you might like the automatic conversion of your objects into a JSON representation. As VBScript does not support introspection (reflection) it is necessary to built an own work around. If you want the JSON class to recognize your custom objects it is necessary to implement a reflect() method within the custom type. reflect() must return a dictionary with all properties where each key is the property name and the value is its value. Values can be all kind of types (because its resolved recursively anyway). The following example shows a “Person” class which implements reflect() and therefore can be used within the JSON generator:

  1. class Person
  2.     public firstname    ''[string] firstname
  3.     public lastname ''[string] lastname
  4.     public favNumbers   ''[array] persons favorite numbers
  5.  
  6.     public function reflect()
  7.         set reflect = server.createObject("scripting.dictionary")
  8.         with reflect
  9.             .add "firstname", firstname
  10.             .add "lastname", lastname
  11.             .add "favNumbers", favNumbers
  12.         end with
  13.     end function
  14. end class

The following example access the properties of the VBScript Person class within JavaScript (as it would be a JavaScript object).

  1. <%
  2. set p = new Person
  3. p.firstname = "John"
  4. p.lastname = "Doe"
  5. p.favNumbers = array(2, 7, 234)
  6. %>
  7. <script>
  8.    alert(<%= (new JSON).toJSON("p", p, false) %>.p.favNumbers[0]);
  9. </script>

Update 10.07.2008: as the toJSON() method has been defined as default method it can be used much quicker by leaving the methodname out:

  1. <script>
  2.    alert(<%= (new JSON)("root", "some value", false) %>.root);
  3. </script>

Those examples are really straight forward and should just demonstrate how to use the generator. Normally you don’t really deal with that as a client, you’d rather have some nice classes which do all this stuff for you. In another article I will demonstrate how to combine ASP, JSON and AJAX in a nice and effective way…

The download of the class is at the bottom. Here is a list of the features..

  • Transforms various datatypes from ASP to Javascript using JSON
  • Escapes all characters which needs to be escaped according to JSON’s RFC
  • Recursively inspects the values so nesting of values is supported
  • Results can be returned or (for better performance) written directly to the response

Have fun with it. There are other article related to this topic which might be interested for you:

Download latest JSON ASP utility class:
JSON 1.5.1 (JSON documentation)

License:
Use it for whatever you want but be sure to leave the credits to the creator(s) within the code. If you don’t change it you can get always the latest update here ;)

Change Log:
v1.5.1 (15.07.2008)

  • bugfix: didnt work properly with empty dictionaries. fixed!

v1.5 (10.07.2008)

  • bugfix: utf-8 fully supported now (e.g. chinese didnt work)
  • bugfix: empty dictionaries werent represented. now represented as ‘null’
  • toJSON() is defined as default method
  • paged recordsets supported
  • asp request object, IStringList and IRequestDictionary supported
  • updated documentation
  • detailed information (examples, …) about the changes

v1.4.1 (19.12.2007)

  • minor bugfix immediately after the 1.4 release

v1.4 (18.12.2007)

  • there used to be an error when returning custom objects which were processed recursively. it resulted in outputing only ‘}’. this has been fixed.
  • vartype 19 was not recognized as integer, but is now (comes from mysql)
  • vartype 7 was not recognized as float, but is now

v1.3 (21.08.2007)

  • Option Explicit can be used now
  • Multidimensional arrays are supported (unlimited dimensions)

v1.2 (19.07.2007)

  • Nested dictionaries were are not generated with toResponse = false. Fixed
  • Currency and Byte datatype were not generated correctly. Fixed

v1.1 (17.05.2007)

  • Bug with Floats has been fixed
asp-ajaxed
JSON is part of ajaxed. So you can check the ajaxed discussion group for more discussion about it.

193 comments on “Generate JSON from VBScript (ASP) datatypes

  1. ASP is not a language that has datatypes. I think you are talking about vbscript, but you need to remember that not even vbscript has datatypes per se. It has subtypes, but all variables are variants - yes, it is a fine distinction. Also, ASP can use jscript as well as vbscript in server-side code. Will your converter handle a jscript array as well as a vbscript array?

  2. hi bob, i am aware about the types (not types) in vbscript but i think you know what i mean ;) for jscript i dont think that it will be implemented … at least not soon…

  3. The License.txt is missing in the root JSON directory. Under what license did you release this great solution? May the JSON ASP file be used for commerical development?

  4. hi tom i’ve just added a license note. you can use it for commercial development and your feedback is welcomed if you have any suggestions for improvements.

  5. Great work, I only wish I had access to this resource last year :)

    Keep up the good work!

  6. Do you have a ASP Jscript version of this?

  7. I’m not entirely sure how to incorporate this class into my app to turn a datatable into a JSON string (as well as the other way around).

    But I think it’s a fair bit more complicated than this is it not?

    Dim dt As DataTable = readRecords()
    response.write(json.toJSON(“records”, dt, False))

    would simply give me

    {records:
    [
    {
    col1:val1_1,
    col2:val1_2
    },
    {
    col1:val2_1,
    col2:val2_2
    },
    ]
    }

  8. @trent: no sorry unfortunately not cause i am using just vbscript for my ASP apps. maybe someone could come up with a clone ;)

  9. hi dave, i wonder how you managed to run this within because it is supposed to work with classic ASP only. If you are looking for generator for check there should be some links…

  10. True. I didn’t actually get it working. I found a C#.NET class from NewtonSoft.

  11. i just googled it and here is the URL for all who are interested in an : in .net its even possible to serialize whole custom types which is not possible in classic ASP unfortunately. no iteration possibility through properties of classes :(

  12. I want to give you some special thanks for your great work, but I still have a problem: does a function which automatic generates variables/objects/arrays …. from a json string (send to server by ajax call) exist? There’re many good-working functions like that in other languages, but in asp (with vbscript), I’ve found none :(

  13. You mean a JSON parser dont you? so also the other way round.
    JSON => ASP

  14. I’ve upped an updated version which fixes the “floats” bug. When using float it generated an integer and dropped the comma. this is fixed now.

  15. Hey Bob,
    I think you’re maybe over-thinking & dealing with semantics here. Clearly VBScript is the dominant language for Classic ASP. As for data types, yes there may be a fine distinction, but the truth is that the distinction doesn’t really matter when the end goal is to correctly translate the value into another format. The point is that ASP(VBS) gives you a hint as to what kind of data you’re working with and that can be used to correctly translate the value into a JSON object.

    I would imagine anyone willing to go through the headaches of using JScript and VBScript in the same file would be able to modify the class to allow for JScript arrays. Inline JScript is parsed & run before any of the VBS on a page, so other than returning an array from a JScript function I wouldn’t personally see much benefit in it. The mingling of VBS & JScript in a single file is definitely a huge weak spot in classic ASP that will never be fixed.

  16. Michael, if you’re interested. I’ve found a few quirks & added a few things to the class. I can clean up the work & send it to you.

    The main quirk I’ve found is that nested Dictionaries trash the result. So lets say you create a dictionary of peoples names and every entry contains a dictionary of phone number, address, email, etc… Your JSON class just outputs:

    }}

    As for additions. I often use an ASP class I created that does a very similar thing to yours, only it does it with XML. My class also examines the data types and translates values as needed for items like arrays & dictionaries, and will nest to a (theoretically) unlimited depth. Like your class, one limitation is the ability to handle custom class definitions.

    While VBScript itself offers no inherent introspection for custom classes, the simple fox is to allow the developer of the class to implement JSON support which your class can then use. With minor changes I gave your class the ability to examine a custom class to see if it supports a ‘toDictionary’ property. If it does, then it will use the value returned from that method, rather than the object itself, and treat it as a dictionary.

    On the class developers side, they only need to implement a toDictionary method, which will grab any relevant values inside of the instance of their class and return a dictionary of name/value pairs. The items in that dictionary should be able to be of any type, including other objects, though the quirky nested dictionary bug I experienced would probably break that. Any class that does not support the method is treated as it is in your original class.

    Anyway, I’m happy to send you the changes if you want them. I’m assuming you have my email from this post.

  17. I have have a need to retrieve values from a database using an ajax call. I have a form that I am collecting information on, I need to retrieve a database based on the values collected in the form (Pass some parameters to the database call), Once retrieved I need to perform calculations based on the retrieved data and submit the form for storage.
    I guess I can use the jason example to call the database values, but I want to retrieve the database without submitting the form. Will anything here you discussed to that?

  18. hi cliff thanks a lot for your very helpful comments and its cool to see that ppl r using this stuff - especially still classic ASP ;) i am really interested in your cleaned up version and droppped you an mail about it. the introspection aproach sounds very interesting and i’ll take a look into it when i have more time … cheers

  19. @vince: if you want to solve this with Ajax it should be a good way to use JSON for that and in this case that utitlity class. i am not sure how fit you are with asp but the following steps should help you:

    - create one page which generates the DB call and uses the JSON class to generate JSON output
    - create another page which holds the form and calls the JSON page with an XHR (e.g. Prototype) to retrieve the values.

    if you need help just let us know here …

  20. great helful. thank you~ ;)
    but , i met some problem using toJSON function

    foo.add “aaa”,”bb/cc”

    using “/” in Dictionary . runtime error occured =(
    how can i fix it? i want to use “/” ..

    help plz.

    um.. have nice day~ :)

  21. @moondy2: sorry for that but there was a function missing within the class. There was a wrong version available … please download the current version and it will work. greets michal

  22. Thank you very much Michal!

    I’m so glad that there are people out there that develop for Classic ASP.
    your script really does saves time!
    and your site is now in my Fav’s for sure :)

  23. I have a question:

    i’m working with your code with recordsets. everything seems to work well..even records that are in hebrew, but dates.
    for some reason all the dates turned up like this:
    lastlogindate”: “16u002F05u002F2007 16:51:32″
    any idea how to solve this?

  24. hi uri, as your date has the following format 16/05 it includes a solidus (/) which needs to be escaped due to the JSON specification. if you use e.g. Prototype () to parse the JSON output this will be parsed correctly.

  25. Grammar != Grammer

  26. hi michal, my situation is like this: im working with Ext.
    With your script I made an .asp file that takes my ms sql database puts it in a rs and writes it in a json format.
    and from the ext I make a grid that takes this date.

    where should I transform the sql date format into a json date format and how?

  27. you need to parse the JSON string first. i dont know the ext-library but ive found a JSON class .. so after the XHR you should parse the response first

  28. michal, thanks for your help.
    in the end i solved my problem by removing the procedure that checks for special chars in your script.
    because what I saw that Ext can handle special chars because the JsonReader is parsing the json code.

  29. Do you know any JSON parser ? JSON => ASP

  30. Yeah, that would be nice!

  31. JSON => ASP? like so:

    var json = {“widget”:[{"value":"text here"},{"value":123}]};


    Next
    Response.Write json.widget.[0].value
    %>

  32. Let’s try that again…

    <%@ Language=VBScript %>
    <script language=”jscript” runat=”server”>
    var json = {“widget”:[{"value":"text here"},{"value":123}]};
    </script>
    <%
    For Each o In json.widget
    Response.Write o.value & “”
    Next
    Response.Write json.widget.[0].value
    %>

  33. Rather than lowercase all of the field names, I prefer camel-case so I changed line 126 to:

    toJSON lCase(left(val.fields(i).name, 1)) & right(val.fields(i).name, len(val.fields(i).name) - 1), val.fields(i).value, true

  34. Declaring cDoubleQuote (const), cRevSolidus (const), cSolidus (const), i (dim), currDigit (dim) in the escape function as well as declaring i (dim) in a few other functions allows this script to run with “Option Explicit”.

  35. Pingback: CrayonCowboy Ranch » Parsing JSON With Classic ASP (VBScript)

  36. Michal, your readers of this post might e interested in this post I just made about parsing JSON with VBScript.

    Actually, its a VBScript class (free for private or commercial use) that allows you to easily parse JSON and get at the data from VBScript. Its got a few rough edges but I plan on ironing those out soon. Still, I’d like some feedback if anyone has any problems with it.

  37. that some fine and helpful code!
    thank you very much Cliff and Michal!

  38. hi, i have some confuse of the function “getRecordset” at your examlp,

    how to get the data form database?

  39. which example do you mean enotsl ?

  40. The first example

    ASP:
    set RS = getRecordset(“SELECT * FROM table”)
    response.write((new JSON).toJSON(“rows”, RS))

    the function “getRecordset”

    thanks!

  41. the getRecordset is just an example how i query data from database. it needs to return an ADODB.recordset object … which could look like this

    1. function getRecordset(sql)
    2.    set getRecordset = conn.execute(sql)
    3. end funciton

    ‘conn’ must already hold an opened database connection.

  42. oh, i see, Thanks Michal

    and one more question, do you know how to transfer Json to asp array?

  43. I’ve been trying to use this library but it “chokes” (hangs and times out) any time I try to use it on a recordset of around 100 rows. I’ve tried it on the raw ADODB recordset and I’ve tried converting to an array using GetRows() but it doesn’t make any difference.

    I have specified the property that makes the object write the JSON strings immediately rather than appending them.

    Has anyone else had problems like this?

  44. I LOVE this utility, but I’m having trouble taking the next step. I can produce the JSON output OK, but when I try to use the generated data, nothing happens. I believe it has something to do with the “callback”, but I can’t find a VBScript example that I could use with the JSON.asp utility that would format the data properly for consumption by an EXT grid widget.

    Here’s what I’ve tried:

    I’ve tried many different variations of this to no avail. I’ve even tried to replicate the data from their grid example on my local server and it just spins for a bit and returns no data even though when I compare the output from my test.asp script to the php script they use in the example they look identical.

    Any help would be appreciated!

    Keep up the good work!

  45. Brett,
    Just a few debugging tips…
    You’re really dealing with two systems here:
    - ASP Creates JSON
    - Your (presumably JavaScript) widget generates a display based on JSON input.

    So you’re going to first need to find the weak link.
    If it were me, I’d begin by trying whatever grid widget you’re using and have it reference hand coded JSON data in a text file. If it works, you know it’s a problem with your JSON output system. If it does not work, you can assume that the problem is possibly in the widget itself.

    The point is you need to break your troubleshooting down into smaller, easier to answer, questions.

    Also, if you’re looking for help with a specific widget, it’s probably helpful to provide a link to the widget you’re using so anyone interested in helping can take a look & see what you’re working with.

    First step is see if the widget works with correctly hand coded JSON. Good luck.

  46. Thanks Cliff! I took your advice and it looks like the problem is with the widget, so I’ll post my questions over there.

    I was trying to get the EXT grid widget to work. The documentation can be found at . Navigate to Examples and Demos > Grid > Paging and Remote Datasets to see the specific example I’m trying to make work.

    I believe the JSON part is correct, so I’ll focus my attention on the widget.

  47. Hi Brett, I have experienced working with Michal’s JSON.asp and Ext Js’s Grid component with great success.
    I’ll tell you how I worked with it, and maybe it will help you.
    First of all I recommend you to see the screencasts about editable grids (part II, but for background you should watch the first one as well - )

    I have a grid.js file that is basicly the whole grid mechanism. it retrives the grid’s data from ajaxasp2.asp like this:

    function setupDataSource() {
    ds = new Ext.data.Store({
    proxy: new Ext.data.HttpProx({url:'ajaxasp2.asp'}),
    reader: new Ext.data.JsonReader(
    {root: 'data', id: 'itemid'},
    [
    {name: 'itemid', mapping: 'itemid'},
    {name: 'itemname', mapping: 'itemname'},
    {name: 'itempath', mapping: 'itempath'},
    {name: 'itemprice', mapping: 'itemprice'},
    {name: 'itemwidth', mapping: 'itemwidth'},
    {name: 'itemheight', mapping: 'itemheight'}
    ]
    )});
    ds.load();
    }

    aspajax2.asp has a very simple code in it. it basicly calls my MSSQL server, takes the data from the table and parse it to JSON (with Michal’s great script):



    Now, Ext has it’s own JSON parsing system, and Michal’s code generates special chars for ” etc.. My SQL’s datetime looks like this 20/07 so I had to remove the part that handle special chars from Michal’s code. the escaping part…


    public function escape(val)
    cDoubleQuote = &h22
    cRevSolidus = &h5C
    cSolidus = &h2F

    for i = 1 to (len(val))
    currentDigit = mid(val, i, 1)
    if asc(currentDigit) > &h00 and asc(currentDigit) = &hC280 and asc(currentDigit) = &hC380 and asc(currentDigit)

    That's it....
    I hope it helped

  48. hmmm… i don’t know what happen to the code so i’ll try again:

    ajaxasp2.asp looks lik that:


    and i disabled the following lines from JSON.asp:

    ‘ elseif asc(currentDigit) >= &hC280 and asc(currentDigit) = &hC380 and asc(currentDigit)

  49. well i see what went wrong…i hope this time it will work:

    Response.ContentType = “text/html; charset=windows-1255″
    Set rs=Server.CreateObject(“ADODB.RecordSet”)
    rs.Open “SELECT * FROM ItemList”,conn,3,3
    response.write((new JSON).toJSON(“data”, rs, false))

  50. hey guys i have updated the class a bit. Now its possible to support your own custom classes. Implement a reflect() method and then its possible to access your objects within JavaScript. Works very nice!! Thanks to Cliff!

  51. can you elaborate? maybe an example?
    Thanks,
    - Uri

  52. @Uri the examples are in the post .. i have updated it

  53. I can´t figure out how to build this structure from a recordset:

    [
    {“text”: “A”,”id”: “A”,”cls”: “folder”, “children”:
    [
    {"id": 31704,"text": "Anker","leaf": true,"cls": "file"},
    {"id": 31600,"text": "Auto","leaf": true,"cls": "file"}
    ]
    },
    {“text”: “B”,”id”: “B”,”cls”: “folder”, “children”:
    [
    {"id": 31804,"text": "Baum","leaf": true,"cls": "file"},
    {"id": 32587,"text": "Box","leaf": true,"cls": "file"}
    ]
    },
    ]

  54. @rene: this structure is not really possible out-of-the-box by the JSON generator. the recordset is parsed in a different way

  55. hi JSON interested guys .. i have written a small ajax library for classic ASP .. you might be intereste. have a read on the first tutorial here:
    https://www.webdevbros.net/2007/07/02/ajaxed-calling-server-side-vbscript-procedures-from-client-side-equivalent-to-php-xajax/

  56. And here you can find how to READ JSON from ASP :)

  57. Media*A : Nice tip but that’s not really reading JSON with ASP. That just illustrates the process of using the Microsoft.XMLHTTP object on the server side to fetch content, it wont really do anything but pass the JASON off to client side JavaScript. It’s still useful though.

  58. NESTED DICTIONARIES BREAK IT!!

    This was noted by Cliff a ways down in the comments and I am having the same problem. The only thing that is output is:

    }}

    Can you please fix this?!! I would love to use it, but I use nested dictionaries a lot!

  59. The nested dictionary problem was being caused by the way you are doing your recursion. When the nested dictionary finishes, it sets recursiveGenerationCall = false, which in turn causes output to be set to an empty string. The fix is to make only the final dictionary set recursiveGenerationCall = false, which I implemented with a stack counter. However, the whole problem is really being caused by the way you are doing your recursion. Rather than using write(), you should be returning the string from toJson() and then concatenating that string to the current output all the way back through the recursion process.

    Anyway, here is my fix:

    line 22: private output, recursiveGenerationCall, dicStack
    line 33: dicStack = 0
    line 115 (and following):
    elseif typename(val) = “Dictionary” then
    if dicStack = 0 then
    recursiveGenerationCall = true
    end if
    dicStack = dicStack + 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(“}”)
    dicStack = dicStack - 1
    if dicStack = 0 then
    recursiveGenerationCall = false
    end if
    elseif typename(val) = “Recordset” then

  60. To be honest, I’ve never seen the need or usefulness of the recursiveGenerationCall flag. I think the finction can determine wether its recursive or not on its own based on data type without needing a variable to hold a status indicator. I’d provided a modified version that handled recursion a bit differently, and is a bit more “all-purpose” that the current version. Granted it amounts to a pretty significant deviation from the original class, but I find it preferable since it applies to any data type that can possibly handle recursion (including custom classes). Michal has the modified version if its of any use in the future.

  61. Cliff,

    Can you please send me your version? My email:

    remove ‘.remove-spam’ (but you probably figured that out).

    Thanks.

  62. Hi all!

    I’ve been playing with this handy utility since yesterday, and I’ve come across a small hitch. I to am using this tool to fill an EXT grid control. For the basic grid, I had no problems whatsoever. But now I wish to impliment a pager for the grid, and so I need to add a property to the root of the json, but can’t think how to do it.

    Basically, I need this:

    {
    “total”:”125″,
    “rows”: [ { "id": 65,"username": "Wmensen" }
    ,{ "id": 101,"username": "etc...." }
    ]
    }

    But I can’t for the life of me think how to insert the “total” property into the results neatly.

    I suppose I could simply parse the string, add the property, and re-assemble, but that seems silly.

    What would the ‘RIGHT’ way to do this be?

    Brian

    • I know this is an old post but I just realized how to do this and though others may want to know.

      I made a dictionary, added the proporties I needed, then when using toJSON I set the label to Empty instead of any kind of string.

      Something like this:

      set d = server.createObject(“scripting.dictionary”)
      d.add “page”, 1
      d.add “total”, 1
      d.add “records”, 6
      d.add “rows”, rsEquipmentList
      response.write( (new JSON).toJSON(Empty, d, false) )

  63. Randy,
    I have no objection to you using my code, but this is Michal’s project and my version is quite a bit different in some ways. I’d much rather have him maintain control of the project without stepping on his toes. :-)

    He does have the last version I put together so you’re more than welcome to contact him & request it. He’s incorporated the ability to serialize (“reflect” I believe is his method name) custom classes so maybe some of the other options will make their way in as well. I’d love to see some of the other additions from my version like supporting Session, Application, and Request collections.

    Anyway, hope it’s not rude to keep my version under wraps, but its Michal’s project & it really should go through him.

  64. Hi brian, in order to achieve this structure i would put the following code into a seperate page:

    1. <!--#include file="JSON.asp"-->
    2. <%
    3. set j = new JSON
    4. j.toResponse = true
    5. with response
    6.     .write("{")
    7.     j.toJSON "total", 125, true
    8.     .write(",")
    9.     j.toJSON "rows", array(1, 2, 3, 4), true
    10.     .write("}")
    11. end with
    12. %>

    You could achieve the same also with “toResponse = false” by concatenating the string … but this is nicer and also much faster. The whole trick here is that you mark your two name-value-pairs as already nested (third parameter of the toJSON method).

  65. @Randy and NESTED DICTIONARIES: could you please show your code where you use nested dictionaries? because for me its working fine … check the following example:

    1. set j = new JSON
    2. j.toResponse = true
    3.  
    4. set d = server.createObject("scripting.dictionary")
    5. d.add "d-1-1", "something"
    6. set d2 = server.createObject("scripting.dictionary")
    7. d2.add "d-2-1", "hello"
    8. d2.add "d-2-2", true
    9. d.add "d-1-2", d2
    10.  
    11. j.toJSON empty, d, false

    you could also name the dictionary and then also able to control the “nested” argument. The “recursiveGenerationCall” indicates that the call of toJSON has been made internally and not by the client outside. Maybe the naming is a bit bad ;) but this flag is indeed necessary when you use the toJSON method more than once…

  66. Hi Michal,

    I need to get a JSON string to look like this:


    {"NAME": "misc.jpg","SIZE": 87832,"TYPE": "JPEG Image","DTS": "16/07 16:55:54","FILEURL": "../dim/day/misc.jpg","FILEEXISTED": "NO"}

    meaning without the root name and its brackets.
    how do I do so?

  67. nevermind, i solved it…

  68. Hey Michal,

    I was thinking that maybe the ability to print a single string, eg:


    {"NAME": "misc.jpg","SIZE": 87832,"TYPE": "JPEG Image","DTS": "16/07 16:55:54","FILEURL": "../dim/day/misc.jpg","FILEEXISTED": "NO"}

    should be in the class. the way I did it is when i give the json the name “remove”


    response.write((new JSON).toJSON("remove", oRS, false))

    it doesn’t add the [] part…
    I can send you the code, but I guess you don’t need it.

    and another thing, from my experience - working with your JSON parsing and Ext, the escaping part is making problems, espacialy with dates.
    so maybe the escaping should be called only if the user wants it, with a boolean arg or something.

    just a thought :)

  69. hi uri … its not very wise to include more methods like remove, etc. You should try to come with the right data structure / data type in order to produce the right JSON. The approach of manipulating the JSON output is not good. Show me your code (incl the wanted JSON) and we can think of how to manipulate your input that it fits. Every kind of JSON should be possible with the current version.

    @EXT escaping problem: i always wanted to check the ext library but had no time yet. Will check this and decide how this affects the JSON class. A flag which turns on/off the escaping sound good btw.

  70. Hi Michal,

    I’m working on the Ext UploadDialog Widget. Making it Classic ASP…

    It uses JSON data in 2 places, one in showing the files in the upload dir. which is a regular JSON, which was done with the JSON class easily.

    and the other spot is to add a new file. the script works like this:
    the user adds the file in the form (input type=”file”) and then in the server side script it uploads the file and returns a JSON string that need to look like this:


    {"NAME": "misc.jpg","SIZE": 87832,"TYPE": "JPEG Image","DTS": "16/07 16:55:54","FILEURL": "../dim/day/misc.jpg","FILEEXISTED": "NO"}

    with this information the Ext UploadDialog knows which file was edited, if it’s a new one it will add a new row and if not it will just update the information.

    the full Ext code can be found in the link above.

  71. uri you can easily do this the following way:
    1) create a page which does the upload (maybe a parameter for new/existing)
    2) when the upload is finished you can return a dictionary the following way:

    1. <!--#include file="json.asp"-->
    2. <%
    3. set j = new JSON
    4. j.toResponse = true
    5. set d = server.createObject("scripting.dictionary")
    6. with d
    7.     .add "NAME", "misc.jpg"
    8.     .add "SIZE", 87832
    9.     .add "TYPE", "JPEG Image"
    10.     '....
    11. end with
    12. j.toJSON empty, d, false
    13. %>

    this will return you the desired JSON output.

  72. ohh thanks Michal!

    I didn’t know that with Dicionary I can achive what I needed

  73. Concerning the nested dictionaries, this code outputs “}}”:

  74. Lets try this again: the code that caused dictionary problems:

    <!-#include file=”JSON.asp”->
    <%
    Dim dicMain, dicSub
    set dicMain = Server.CreateObject(“Scripting.Dictionary”)
    set dicSub = Server.CreateObject(“Scripting.Dictionary”)

    dicSub.add 1.1, true

    dicMain.add 1, dicSub

    dim sOutput
    sOutput = (new JSON).toJSON(“data”, dicMain, false)
    response.write sOutput

    %>

  75. Hi Randy, thanks for your snippet. I found the problem now. It was only working directly to the response … thats why I never experienced it because i usually let the JSON generator output directly to the response.
    I solved it in a similar way you posted it once (stackcounter) but i also removed the recursiveGenerationCall flag.
    I also did some small refactoring and added support for currency and byte.

  76. Thanks!

  77. One last thing. The class does not work when OPTION EXPLICIT has been declared. Can you update that?

  78. Hey Michal,

    Just wanted to say that the Dicionary solution for my problem worked smoothly.

    Thanks!

  79. Hi,

    in your actual version i missed a support for 2 dimensional arrays.
    Here is my solution:


    '******************************************************************************************************************
    '* proof array dimension
    '******************************************************************************************************************
    function isArrayMulti(inArray)
    isArrayMulti = false
    on error resume next
    dim tmpVar
    tmpVar = inArray(0, 0)

    if err.number = 0 then
    'the array is useable...
    isArrayMulti = true
    end if
    end function

    '******************************************************************************************************************
    '* generateArray
    '******************************************************************************************************************
    private sub generateArray(val)
    dim i,j
    write("[")
    if isArrayMulti(val) then
    for i = 0 to uBound(val, 2)
    if i > 0 then write(",")
    write("[")
    for j = 0 to uBound(val)
    if j > 0 then write(",")
    generateValue(val(j, i))
    next
    write("]")
    next
    else
    for i = 0 to uBound(val)
    if i > 0 then write(",")
    generateValue(val(i))
    next
    end if
    write("]")
    end sub

  80. Hi Michal, thanks for your script. It surely does look nice. Whilst browsing through your code and searching the comments here I however did not find a decoding function. Do you happen to know if such a library or function exists somewhere?

    Thanks in advance.
    Bram.

  81. Missed nicer date handling in the JSON class. So I wrote my own in…


    ‘single, double, currency
    elseif varType(val) = vbSingle or varType(val) = vbDouble or varType(val) = vbCurrency then
    write(replace(cDbl(val), “,”, “.”))
    ‘date
    elseif varType(val) = vbDate then
    write(“”"” & Year(val) & “-” & _
    Right(100 + Month(val), 2) & “-” & _
    Right(100 + Day(val), 2) & “T” & _
    Right(100 + Hour(val), 2) & “:” & _
    Right(100 + Minute(val), 2) & “:” & _
    Right(100 + Second(val), 2) & “”"”)
    else

    Will format it to a friendlier non-US format. Not sure how you’d go about converting it to a JavaScript timestamp though.

  82. i suppose posting 79 shows a bug :)

  83. How would I go about implementing the use of GetRows() array such that I can execute a stored procedure? Is this even possible?

  84. when i call the toJSON method on my custom objects, it appears that their reflect method is never called…

  85. shalom itamar, you should copy/paste your code so we could try to help you….

  86. I am having a problem.

    To start with, my website declares OPTION EXPLICIT, so I went through the JSON.asp file and explicitly declared all the variables.

    Now, here is a sample of my code.

    class Something

    public id
    public name

    public sub class_initialize()
    id = empty
    name = empty
    end sub

    public sub class_terminate()
    id = empty
    name = empty
    end sub

    public function reflect()
    dim map: set map = server.createobject(“scripting.dictionary”)
    with map
    .add “id”, id
    .add “name”, name
    end with
    set reflect = map
    end function

    end class

    class SomethingList

    public a

    private sub class_initialize()
    set a = server.createobject(“scripting.dictionary”)
    end sub

    private sub class_terminate()
    set a = nothing
    end sub

    public function addsomething(byref b)
    a.add(b.id, b)
    end function

    public function reflect()
    set reflect = server.createobject(“scripting.dictionary”)
    with reflect
    .add “length”, a.Count
    .add “items”, a.Items
    end with
    end function

    end class

    Please don’t mind any small syntatical mistakes, I am typing in by hand.

    When I want to convert a SomethingList to JSON, I proceed with the example that you have here, , but it does not call the reflect of the individual Something objects, it just returns their type name.

    I played around with it and to make it work this is what i did:

    where somethinglist is a variable of type SomethingList

    also, when i was checking for why this was happening, i removed all the error catching statements and no errors are occurring.

    for a live example:

    the -noreflect means that I called toJSON without explicitly calling the list’s reflect method.

    btw, my email is, if you have any questions it would be quicker to mail me directly.

  87. sorry, the examples were taken out, here they are again.

    what works:
    (new JSON).toJSON(“list”, somethinglist.reflect(), true)

    what doesn’t:
    (new JSON).toJSON(“list”, somethinglist, true)

  88. Small typo in the documentation

    set RS = getRecordset(“SELECT * FROM table”)
    response.write((new JSON).toJSON(“rows”, RS))

    -> Should be

    set RS = getRecordset(“SELECT * FROM table”)
    response.write((new JSON).toJSON(“rows”, RS, false))

    Rgds
    Martin

  89. Hmm… looks like I’ve been away for a while. I kinda just *stopped* checking email. :-)

    Michal, a few posts ago you wrote:
    “The “recursiveGenerationCall” [...] is indeed necessary when you use the toJSON method more than once…”

    It’s your code so do it the way you want, but the reason it’s needed in your version is that you’ve got a lot of things built into one function that could definitely be broken out into other private methods. There is no real inherent need for the flag because the private functions should be able to encode any object at any depth as its own JSON object and return it to whatever is calling it. It really shouldn’t matter if it’s being called internally or externally. The version I sent you a while back didn’t require the flag.

  90. Bramus, that question came up pretty early on in the comments so you’d have to jump back a ways to see it. Try:

  91. hey guys thanks for your great feedback .. i have considered as much as possible for now and released a new version (1.3) which can be easily replaced in your projects …

    - it can be used with option explicit now
    - multi dimensional arrays are supported now (thanks FUSiON for the suggestion)

    @itamar: the bug you have experienced should be fixed now … this had to do with the “option explicit”. you might forgot to dim the “props” variable. Thanks for your detailed comment!

    i am looking for feedback guys … ;)

  92. I would recommend that you update the “Known bugs” section on your blog and make it a “Change Log” instead. Then, make sure you update it when you make changes to the code. That lets someone know that the project is active and knows what issues have been addressed without having to sift through the many comments.

  93. thats a good point randy .. ive changed it.

  94. Looks great! Much more intuitive IMO. Except for those European dates, boy they throw me for a loop. ;)

  95. Nice Job!
    Thanks!this is just what i wanted!

  96. Very nice class, exactly what I was looking for. Perhaps in a next phase you could add a JSON => ASP conversion.

  97. Michal: First, thanks so much for making your library available to the classic asp community. I am trying to build json to use with zapatec ajax components. An example of their required format for a data set with the fields (Country, Population, Titlte, GDP, Birth Rate per 1000, Life Expectency, Internet users, Continent) with 2 rows of data for Afghanistan and Zambia is as follows.

    {“fields”:[{"title":"Country"},{"title":"Population","dataType":"int"},{"title":"Area","dataType":"int"},{"title":"GDP","dataType":"int"},{"title":"Birth Rate Per 1000","dataType":"float","columnWidth":"110px"},{"title":"Life Expectency","dataType":"float"},{"title":"Internet Users","dataType":"int"},{"title":"Continent"}],”rows”:[{“cells”:[{"v":"Afghanistan"},{"v":29928987},{"v":647500},{"v":21500000000},{"v":47.02},{"v":42.9},{"v":1000},{"v":"Asia"}]},{“cells”:[{"v":"Zambia"},{"v":11261795},{"v":752614},{"v":10280000000},{"v":41.38},{"v":39.7},{"v":68200},{"v":"Africa"}]}]}

    As you can see, it needs to be prefaced with a dictionary and all values must be tagged with a “v”. I was successfull in getting your library to run and generating some json but not in Zapatec’s format. I am a little lost. Can you show me an example with at least a few fields of how I could use your library to build such a statement? Any help would be most appreciated.

    THNX

  98. I’m fixed multidimension array to single dimension generated code region. It working, multidimensiton to multidimension array node. Contact me.

  99. I publish a fixed version. Changed escape function rename to JEscape, because runtime function exist named. Multidimension problem fixed. It generating multi dimension array to multi dimension array JSON node now. Download publish .

  100. Hi Michael,

    Great class… definitely came in handy.

    I added a small mod to generateRecordset to support paging. I added the code below just after val.movenext() within generateRecordset. I also added pageNumber, which is a new public property. The caller is responsible for setting this value as well as setting rs.PageSize and rs.AbsolutePage of the recordset.

    if not val.eof then
    if pageNumber > 0 then
    if val.AbsolutePage pageNumber then Exit Do
    end if
    write(“,”)
    end if

  101. Hey Michael,

    I ended up adding one more small thing to generateRecordset. I added the record count at the end of the output. I mainly added this to support paging so that you’d be able to display something like ‘Displaying 25 - 50 of 255′ if needed. Here’s the code I ended up changing.

    I replaced:

    write(“]”)

    with this

    write(“],”)
    toJSON “recordcount”, val.RecordCount, true

  102. WOW, thanks.
    I finally got to play with this a little more.
    I ran into a problem where I am doing something like this.
    var jsonstring =
    var jsonObj = (”).parseJSON()

    Some of my data is like this…
    “Trey’s Code”
    Not sure if it JSON that does not like it or your conversion should account for that, or even I need to specify some parameter.
    By doing this.

    var jsonstring =
    var jsonObj = (”).parseJSON()

    I was able to remove that darn javascript error about.
    Expected ‘)’

    I’m doing the above in a test bed, so it may act differently when I am transferring the data between ASP pages.

    Any thoughts?
    Using the 1.4 version.

    Thanks.

  103. ARGH, can’t please the parsing engine.
    I give up.

    I will leave it as,
    Great job.
    Nice work
    The comments parser sucks. :)

    Will give this a try…

    WOW, thanks.
    I finally got to play with this a little more.
    I ran into a problem where I am doing something like this.
    var jsonstring = <% =((new JSON).toJSON("rows", ProdArray,false)) %>
    var jsonObj = (‘<% =jsonstring %>’).parseJSON()
    Some of my data is like this…
    "Trey’s Code"
    Not sure if it JSON that does not like it or your conversion should account for that, or even I need to specify some parameter.
    By doing this.
    var jsonstring = <% =replace(((new JSON).toJSON("rows", ProdArray,false)),"’","’") %>
    var jsonObj = (‘<% =jsonstring %>’).parseJSON()
    I was able to remove that darn javascript error about.
    Expected ‘)’
    I’m doing the above in a test bed, so it may act differently when I am transferring the data between ASP pages.
    Any thoughts?
    Using the 1.4 version.
    Thanks.

  104. Wow. I just came across this while struggling to inject ajax js ‘calendar’ objects with data from serverside asp. If this class works with 4 levels of nested arrays, you become my new hero — or life!

    Michal, thanks so much for all your contributions to the asp code community. I still extensively use your asp debug class when working in classic asp, it’s saves my arse avery day.

    Cheers mate. Thanks for another great tool.

    Dave

  105. Just a quick FYI aboutv 1.4 -

    anyone trying to use ‘json v1.4′:
    (as referenced in the comments #99 & #98 below, coded hosted and altered/maintained by Tugrul TOPUZ)

    v1.4 doesnt function w/ correct behavior for multidimensional arrays as posted. Running a quick test using the test data provided by Tugrul for his v1.4 class, on a 4d array, returns a JSON string of:
    {“four”: [[[[,],[,]],[[,],[,]]],[[[,],[,]],[[,],[,]]]]}

    v1.4 also returns incorrect JSON using michal’s example data above. A call to v1.4 for the following non-multi dimensional array is also not working correctly:
    CALL : (new JSON).toJSON(“foo”, array(true, 1, “”), false)
    RETURNS JSON : {“foo”: [,,]}
    INSTEAD OF : {“foo”: [true,1,"x"]}

    Not try to slag Tugrul, or anyone else who’s charing/contributing their code, it’s much all very much appreciated! Im sure he just accidentally linked to a non working release of v1.4.

    Just a head’s up, that v1.4, as currently downloadable, will need vbscript code mods right out of the zip file, before you can use it.

    Dave

  106. Just a huge thanks for coding/maintaining/open sourcing this beautiful chunk of code. Works perfectly for me passing quad nested date arrays into a js calendar widget on the fly. Well done, and many cheers, Michal.

    Bug report:
    I hacked up a small batch of unit tests for various types/structures on JSON v1.3 class before I put it into use and noticed the following quirk.

    1. Calling the ‘toJSON’ function using a ‘recordset’ fails to return a JSON string, only ‘[]’ when its called with ‘name’ parameter = empty. I.e.:
    ……..non working call: res = (new cJson).toJSON(empty, rs, False) …………………returns: []
    But the same recset tests totally fine, and as expected, if you include a ‘name’ param as part of the call
    ……..working call: res = (new cJson).toJSON(“myRecSet”, rs, False)
    …………………returns: expected JSON

    2. Also, just a confirmation, as already noted in post #87 & 86 by Itamar Levin below, when calling ToJSON on an user defined object/class using the built-in reflection you must call it using full name of your reflect method. Not just your object name:
    ……..working call: res = (new cJson).toJSON(“myObj”, myObj.Reflect, False)
    ……..non working call: res = (new cJson).toJSON(“myObj”, myObj, False)

    I’m not actually using recordsets or objects for any JSON calls, so I didnt take the time to debug/edit/fix those two, I’m just noting the failed unit tests. If I have some free time over next few weekends, I will do try to take a peek and see exactly what’s failing. In the meantime, just an FYI note for other downloaders of v1.3.

    As always, big thanks to Michal for pouring over the JSON specs & putting together an asp based JSON class for us ‘retro grouches’. ;o)~

    Dave

  107. Is it possible that this class does not handle unicode? When retrieving string data from my dB (SQL2K5) that includes Microsoft Word’s long dash (ASCII 150) and other characters above ASCII 127, the process fails (DOM Inspector: “Malformed URI sequence”). Could there be something I’m missing?

  108. Hi
    Thanks for this json asp class, have succesful made a small test ap with MSSQL + asp and GWT, this whas only a small test app but i worked allright.
    As Clayvahn Hunt says it does have a problem with characters beyone accii 127 , haven’t hade the time to look into way i just made a quick dirty solution to convert those char before i lead asp.json handle them.
    What happens in GWT if it not is handle is that GWT throws a javascript error (unterminated string constant) because the json string back from a rs will look like this
    {“rows”: [{... ,"bem": "b?]}
    but should be this
    {“rows”: [{......,"bem": "bå"}]}

    But anyway …works ok
    Regards Ib

  109. Hello Michal,

    It appears that the JSON parser is encoding forward-slashes (“/”) into unicode. Is this necessary? For example: 10/09 is converted to something like 10u0002F09u0002F2007

  110. @raymond … this is defined in the JSONs RFC

  111. Thought i’d share a problem/solution i encountered. Kept on receiving “Microsoft VBScript runtime error ’800a01ca’ Variable uses an Automation type not supported in VBScript” when generating from recordsets

    Finally tracked it down to the fact that integers within my recordsets came out with a vartype of 19… which seems to be largely undocumented but i beleive is “hard-typed long integer”

    After altering the function generateValue to recognise and output these as long integers everything worked fine.

    Not sure if this has something to do with me using MySQL. It probably does

  112. I think the Dave m Says: October 21stat 1:43 pm ‘s question is right…

    when calling ToJSON on an user defined object/class using the built-in reflection you must call it using full name of your reflect method, it’s not working well.

    i check the code of JSON.asp, and found :: in the function “generateObject”, innerCall ‘s value is 0, and the next call “toJSON Empty, props, true” will call the “newGeneration()” function again, that mean “output” will be destroyed,,

    so nothing happen, when call toJSON with object/class

    i try to add code “innerCall = innerCall + 1″ & “innerCall = innerCall - 1″ in function “generateObject(val)”.. it’s working well.

    i don’t know is this a bug????

  113. @JR: could you show me your usage … because normally it should not be necessary to add this line. thx

  114. i just run the sample code you provided above.
    client.html:
    var myAjax = new Ajax.Request(
    ‘/server.asp’,
    {method: ‘get’, parameters: parm, onComplete: showList}
    );
    function showList(req) {
    $(‘result’).value = req.responseText;
    }

    server.asp:
    class Person
    …… the same with the sample above.
    end class

    set p = new Person
    …… initialize the class. like the example too.

    response.Write((new JSON).toJSON(“obj”, p, false))

    i run the “client.html”, but i get the return value on client.html is “}” only.
    i think
    the first step, call “toJSON(name, val, nested)”,
    the second step, call the “generateObject(val)”,
    and the follow step is call “toJSON Empty, props, true” again.

    at that time , i thought “newGeneration()” will be executed again, and destory the “output”, ’cause the “innerCall = 0″.

    that is, the only return is “if not nested and not isEmpty(names) then write(“}”)”, i mean character “}” only.

    is that right???? i don;t know whether i made the right step. but after i add that lines, it’s working well…

  115. Hi, first, felicitation and many thanks you for your master work!

    Second, I’m not sure but I think that there is bug in the version 1.3: you seem to have forgot to surround the call to toJSON with « innerCall = +- 1» in the sub generateObject(val):


    innerCall = innerCall + 1
    toJSON empty, props, true
    innerCall = innerCall - 1

    Without these, your exemple with the class Person only write the last } as the result.

    Thanks again and Happy Holidays!
    Sylvain Lafontaine, ing.

  116. i’ve just updated the JSON utility class .. fixed some bugs .. check the changelog and download 1.4. Thanks to all who contributed here in the comments.. please keep doing this …

  117. Pingback: Web Dev Bros » Blog Archive » ASP JSON utility class 1.4 released

  118. 1.4 has a minor option explicit issue, the variable varTyp is not declared.

  119. Bug:
    Line 121: “varTyp” is not declared

  120. thanks ddoctor and james for pointing out this problem .. i fixed this issue now and its available in JSON 1.4.1 .. i will write a test to ensure option explicit in the future .. because i am not working with this option normally

  121. Hi there,

    Does this class work with MS Access when generating a recordset? I seem to having problems:

    Wrong number of arguments or invalid property assignment: ‘toJSON’

    What am I doing wrong?

    Thanks in advance

  122. Please disregard my last post I worked it out, I had to do this in the javascript section:

    var myObj = {};

    I originally did this:

    var myObj = ;

    Didn’t realise that I had to include the {} around the JSON object

  123. Don’t use Access for websites. There are many better options, like MySQL.

  124. Now I am new for JSON, so glad to make friends with the person who want to study with me.

  125. The JSON Classic ASP object is very useful. I wanted to point out that there is a constraint on datatype in Access. Automation Objects/binary file formats seem not to be able to be read. Just a heads up for those who may have already hard coded a SQL Query with these “fields” listed.

    The error is reported on line 145 as a Type Mismatch Runtime error. (I think this is because of the for each loop.

  126. Your generateArray subroutine doesn’t quite work for multidimensional arrays - you end up with a single dimensional array with all the values flattened.

    You need a counter array of the same number of dimensions as the original to see when to stop/start the json arrays.

    Use the jScript countDims() function here to get the dimension count:

    Then do:
    private sub generateArray(val)
    dim item
    dim d,c,i
    d = countDims(val)
    redim c(d)

    ‘initialise counts: ubound+1 signals start new array, -1 signals end array
    for i = 1 to d
    c(i) = ubound(val, i)+1
    next

    for each item in val
    for i = 1 to d
    if c(i) = ubound(val, i)+1 then
    write “[”
    c(i) = ubound(val, i)
    end if
    next
    write generateValue(item)
    for i = 1 to d
    c(i) = c(i) -1
    if c(i)

  127. Your generateArray subroutine doesn’t quite work for multidimensional arrays - you end up with a single dimensional array with all the values flattened.

    You need a counter array of the same number of dimensions as the original to see when to stop/start the json arrays.

    Use the jScript countDims() function here to get the dimension count:

    Then do:
    private sub generateArray(val)
    dim item
    dim d,c,i
    d = countDims(val)
    redim c(d)

    ‘initialise counts: ubound+1 signals start new array, -1 signals end array
    for i = 1 to d
    c(i) = ubound(val, i)+1
    next

    for each item in val
    for i = 1 to d
    if c(i) = ubound(val, i)+1 then
    write “["
    c(i) = ubound(val, i)
    end if
    next
    write generateValue(item)
    for i = 1 to d
    c(i) = c(i) -1
    if c(i)= -1 then
    c(i) = ubound(val, i)+1
    write "]”
    else
    write “,”
    exit for
    end if
    next
    next
    end sub

    [reposted as half the sub got cut off]

  128. Hello, I’m just starting to play here with this class and it looks like exactly what I need! I read through all the comments, and a couple seemed like they might help, but no luck. To get me moving in the right direction using this class, can someone tell me how I might generate the following JSON string (it’s dummy data for an EXT toolbar widget).

    [{xtype: ‘tbbutton’,text: ‘Menu 1′,menu: [{text: 'Better'},{text: 'Good'},{text: 'Best'}]},{xtype: ‘tbbutton’,text: ‘Menu 2′,menu: [{text: 'Alpha'},{text: 'Beta'},{text: 'Gamma'}]}]

    Any tips appreciated. Thanks!

  129. I’ve been using ADO recordSet rows converted to WDDX for a while. I just put together a way to take the recordSet XML string and translate it into JSON via XSLT - for those that are exposed to ADO XML without access to ADO (i.e. through an API)

    I’d be curious to see how a somewhat simple XSLT with really simple recursion performs against the JSON generator.

  130. I need help please with the following: from a dropdown combo box on a form the user selects a row and then an onchange-triggered Javascript function needs to retrieve a SPECIFIC ROW from an ADO (MS SQL) recordset on the server, using classic ASP. All examples I have seen create a recordset for an entire table (e.g., “select * from table”). How do I basically do the following?

    where

    i => would be obtained from the JavaScript function called during the onchange event, i.e:

    function getValue(optval)
    {
    var i = optval.value;
    }

    Option 1
    Option 2

    JSON seems great to go from ASP to Javascript, but how does one insert a Javascript variable into ASP code or, asked another way, into an object that will then be run on the server, like the recordset SELECT statement shown above?

    I really, really, thank anyone that can help us!!

  131. Hi Michael

    I need help please with the following: from a dropdown combo box on a form the user selects a row and then an onchange-triggered Javascript function needs to retrieve a SPECIFIC ROW from an ADO (MS SQL) recordset on the server, using classic ASP. All examples I have seen create a recordset for an entire table (e.g., “select * from table”). How do I basically do the following?

    where

    i => would be obtained from the JavaScript function called during the onchange event, i.e:

    function getValue(optval)
    {
    var i = optval.value;
    }

    Option 1
    Option 2

    JSON seems great to go from ASP to Javascript, but how does one insert a Javascript variable into ASP code or, asked another way, into an object that will then be run on the server, like the recordset SELECT statement shown above?

    Thanks!!

  132. Hi Michael

    I need help please with the following: from a dropdown combo box on a form the user selects a row and then an onchange-triggered Javascript function needs to retrieve a SPECIFIC ROW from an ADO (MS SQL) recordset on the server, using classic ASP. All examples I have seen create a recordset for an entire table (e.g., “select * from table”). How do I basically do the following?

    where

    i => would be obtained from the JavaScript function called during the onchange event, i.e:

    function getValue(optval)
    {
    var i = optval.value;
    }

    Option 1
    Option 2

    JSON seems great to go from ASP to Javascript, but how does one insert a Javascript variable into ASP code or, asked another way, into an object that will then be run on the server, like the recordset SELECT statement shown above? The class examples make sense when submitting the entire class itself with JSON, but not the parsing of “ASP SCRIPT” + JS VARIABLE + “ASPSCRIPT” as with my SELECT statement above. Did I miss something somwhere?

    Thanks!!

  133. SORRY - my browser was timing out and I didn’t see the same message posted again and again until I went to another machine. Just one other thing: being new with this website forum I didn’t realize that the ASP snippet I included would not show on the form. Here is that “missing” piece (so that the code sample makes sense). I added “pre” and “/pre” tags in the hope the text comes out as code sample, not interpreted HTML, etc.!

    JP

    [server-side .ASP code starts here]

    set rs = db.getRecordSet(“Select * from mytable where id = ‘” & i & “‘”

    [end .ASP]

    where

    i => would be obtained from the JavaScript function called during the onchange event, i.e:

    function getValue(optval)
    {
    var i = optval.value;
    }

    Option 1
    Option 2

  134. guys i have created a discussion group where you can post your questions.

    this should make the communication much easier

  135. I’ve got a problem.
    I’m using Flash to communicate with an application (.exe) on an other domain (! no webserver but a server at a client) which sends out a json-object after reseiving a request.
    In the Flash IDE all works wonderfull but putting it online (in a .asp/.html file) its not not working anymore because of the crossdomain security.
    Putting a crossdomain.xml in the root of the second domain is not an option because there is no root. It’s an app. (Delphi) listening too a static IP-adress. When recieving a request it sends out an answer.

    Now i want to make a work around so that i can send a request to an .asp file on our server that returns the answer from the client server to the .swf.

    Is there anywhere an .asp sample on how to send a json string (object) and reseive a json answer (string - object) in the same file?
    Hope you understand what i mean.

  136. hi Michal:

    I am sorry.

    It’s not so good for Chinese.

    I come from China.

    I wish it will support more languages.

    Thanks!

  137. I think you don’t make sure that Unicode of this json class as same as your page Unicode, so, I advice that make all pages’ unicode in accord with this class

  138. hi i’m just trying to some thing similar wat u expalained in this post getting data from 1 site and diplaying on the other site using AJAX and asp, but stuck with ajax function can u help me with this pls, thanks in advance.

  139. Similar project by mine. It supported all unicode languages (Chinese, Japanese, Arabic, Turkish and all others ). VBScript multidimensional arrays to JavaScript multidimensional arrays literal. It have a one within the other and improvable architecture.

    Google code wiki content is currently read-only for maintenance. This page have a little examples.

  140. Thank you very much Michal for making your code available, it’s been invaluable for us.

  141. Pingback: ajaxd库 at 忍忍就過了

  142. Got it. Put it in. Worked! Just like that. Thanks for writing a good script.

  143. Wow! We do mostly asp and this will save us a lot of time. Thanks for the resource and code. Keep up the great work…

  144. Pingback: Web Dev Bros » Blog Archive » ASP JSON utility version 1.5 released

  145. hey guys … new version has been release .. thanks big time to all who helped!

  146. Great read, Michal. I”m a seasoned Classic ASP coder (even though I admit it is a dead/dying language, slowly moving to PHP) but it’s folks like you that make us stubborn Classic-ASPers’ lives a bit easier. Good stuff!

  147. Great ajax utility! Thanks for such a great work.
    I am using it in my current job. I just wonder if it is possible to convert Json string back to asp class/dic?

  148. york unfortunately there isnt the otherway round yet … but it will come i think cause i would have needed it as well..

  149. There is a JSON -> ASP library included in this:

    We used it on a project not too long ago. Doesn’t work exactly like I expected it to, but it got the job done.

  150. Pingback: sshlog » Blog Archive » [ASP] asp + jquery + json

  151. I just wanted to leave a note as I used your JSON class and made a small improvement to it. I use my own custom array and associative array classes to make working with arrays and hashes easier in ASP. Adding a reflect method to the associative array class was easy as it simply returned the internal dictionary. The array was harder since your generateObject method expects an object and would not work if reflect returned a simple type. I’ve made a small modification so that a reflect method could return both objects and native types. For example somebody could have some sort of math object and simply return an integer on reflect. Please note that this code works for me but has not been extensively tested:

    private sub generateObject(val)
    dim props
    on error resume next
    set props = val.reflect()
    if err 0 then
    err.clear
    props = val.reflect()
    end if
    if err = 0 then
    innerCall = innerCall + 1
    toJSON empty, props, true
    innerCall = innerCall - 1
    else
    write(“”"” & escape(typename(val)) & “”"”)
    end if
    err.clear
    on error goto 0
    end sub

  152. I like the concept of using Json with Classic ASP. I’m complete lost without a full ASP example of the use of this class. I have no reference on how to apply this library class.

  153. i’ve been looking for way to convert the json string into something (probably object) in ASP classic.
    trully i have no idea if i have to do this by myself…

  154. Hi Michael,

    We are stuck up with ASP on the front end, where as the app layer is being built using WCF. So i was wondering if we can return the data from WCF in JSON format and then convert that data into custom objects on the server using JScript / ASP etc?

    Can you give some ideas please?

    Thanks

  155. i noticed that your examples in this post do not include the 3rd parameter (“nested”) in the call to toJSON. it threw me off for a couple seconds when testing this library out.

    thanks for providing the code!

  156. For anyone interested in decoding the JSON into an ASP object, I would suggest trying the jscript eval function. This has worked for me. Unfortunately, it only works in jscript ASP and most of my code is in vbscript.

  157. Dan - I call JSON.parse() from the standard json.js from VBscript ASP all the time. The only caveat is that the arrays it creates are Javascript arrays - VB sees them as objects with a .length property plus a bunch of numeric properties. Since there is no way to express accessing an numeric property in VB, you have to use a Jscript wrapper function:

    <script type=”text/javascript” runat=”server>
    function arrayValue(a, index) {
    return a[index];
    }
    </script>

    It also means you can’t use vartype or isarray on the array to see if it is an array - you get type 8 (string) from vartype.

  158. Dan - I call JSON.parse() from the standard json.js from VBscript ASP all the time. The only caveat is that the arrays it creates are Javascript arrays - VB sees them as objects with a .length property plus a bunch of numeric properties. Since there is no way to express accessing an numeric property in VB, you have to use a Jscript wrapper function:

    1. <script type="text/javascript" runat="server>
    2. function arrayValue(a, index) {
    3.     return a[index];
    4. }

    </script>

    It also means you can’t use vartype or isarray on the array to see if it is an array - you get type 8 (string) from vartype.

  159. Mike - Yeah, I just ran in to that the other day as I just recently started combining VBScript and JScript in my ASP pages. Makes me wish that I had just been doing everything in JScript from the start. It’s nice to be able to iterate through all of the properties of an object with

    for (var prop in object){
    Response.write(prop + ‘=’ + object[prop]);
    }

    I guess you could write a Javascript function to help you out with that too like

    function iterateObject(obj, fn) {
    for (var prop in obj) {
    fn(prop, obj[prop];
    }
    }

    function callback(property, value)
    response.write property & “=” & value;
    end function

    iterateObject(someObject, getRef(“callBack”))

    Not sure if that would work or not. All I know is it would be a lot prettier in javascript with the anonymous functions and all. like jQuery’s .each(function () {});

  160. The first example may be something wrong . A lack of trust parameter.

  161. i search json parser for asp,but i find nothing
    but i find a easy way to parse json string to Asp Object.it’s very easy.
    i find the topic from here:
    use the server side javascript parser and create a object and return it to your asp code.

    javascript
    < view plain text >
    1. function parseToJson(json_data)
    2. {
    3.     eval("var o=" + json_data);
    4.     return o;
    5. }
    1. if sel"" then
    2.     set json_obj=parseToJson(sel)
    3.     response.write Json_obj.name
    4. end if

    you can try it.

  162. but we cann’t access the item in the jscript array directly,so we need other way to use the json object in asp vbscript
    the following is my code:

    1. if sel"" then
    2.     set json_obj=parseToJson(sel)
    3.     json_len=json_obj.length
    4.     while json_obj.length>0
    5.         if json_len>json_obj.length  then ids=ids&","
    6.         set Json_item=json_obj.pop()
    7.         ids=ids&json_item.id
    8.     wend
    9.     response.write ids
    10. end if
  163. I have a ajax reponse that I would like to insert into a db, the response is:

    1. {"forename":["Forname1","forname2"],"surname":["Surname2","surname2"],"dateOfBirth":["04/07","05
    2. /27/2009"]}

    where forename, surname, dateOfBirth are all the fields in the DB, how can process this information using the insert command?

    I use the JSON to retrive information but not insert anything so any help is appreicated.

    1. INSERT INTO dbo.login_tbl (forename, surname, dateOfBirth) VALUES (value1, value2, value3)

    for each in the array?

  164. i really want it with ASP classic. thank you for works!

  165. Hi,

    When outputting as:

    sqlquery = “Select company, username, useremail, tel, password FROM tbl_login where id = 93″

    sOutput = (new JSON).toJSON(“data”, getRecordset(sqlquery), false)

    I need the output to read:

    “{‘success’:true,’data’:{‘company’:'John’,'username’:'Doe’,'useremail’:'john.doe@example.com’}}”

    At present there is no ‘success’:true in front and there is always an [ ]

    How could add the sucess and omit the [] which I think is an array?

    • @sanj you can’t easily remove the [] as thats the way how the recordset is parsed. It’s an array with “objects’ inside. The success can be appended by e.g. using a dictionary:

      1. set dict = server.createobject("scripting.dictionary")
      2. dict.add "success", true
      3. dict.add "data", getRecordset(sqlquery)
      4. sOutput = (new JSON).toJSON("root", dict, false)
  166. Thanks Michal, is this still the best ASP Json.

    The reason I need the [] removed is becasue of EXTjs loading into aform via a JSON response. I’ve got around this be manually removing it.

    Sanj

  167. Hi,

    is it possible to add more than one sql,

    say I have:

    sqlquery = “SELECT PORev1Name, PORev1Status, PORev1Comments, PORev1DateRev FROM dbo.tbl_uob_main WHERE id = ?”

    dim sOutput
    sOutput = (new JSON).toJSON(“data”, getRecordset(sqlquery), false)

    how could I do the following?

    sqlquerya = “SELECT PORev1Name, PORev1Status, PORev1Comments, PORev1DateRev FROM dbo.tbl_uob_main WHERE”

    sqlqueryb = “SELECT PORev2Name, PORev2Status, PORev2Comments, PORev2DateRev FROM dbo.tbl_uob_main”

    sOutput = (new JSON).toJSON(“data”, getRecordset(sqlquerya) & getRecordset(sqlqueryb), false)

    • @sanj: you have two options .. you can either add both recordsets into an array or into a dictionary. Then transform the dictionary/array with toJSON().

  168. Michal,

    Thanks for your reply, could you please give me an example to convert into an array,

    is the correct way for a dictionary:

    dict.add "success", true
    dict.add getRecordset(sqlqueryA)
    dict.add getRecordset(sqlqueryB)
    sOutput = (new JSON).toJSON("root", dict, false)

    • yes, thats correct. array would be then

      sOutput = (new JSON).toJSON("root", array(getRecordset(sqlqueryA), getRecordset(sqlqueryA)), false)

  169. Michal, cool - what a superb utility!

  170. @Michal Do you have any advice for handling SQL DateTime types from a result set? My dates are coming back like: ’6u002F1u002F2009′ and I need to convert them to a JavaScript date.

    Thanks :)

  171. Can you please explain how to get rid of that [] at the beginning of the RecordSet JSON? It’s screwing things up for me royally.

    Thanks!

  172. I like your program very much and use it a lot. I still have one problem: dateformats.
    Our MSSQL server is English, our webpages are Dutch. Json returns the MDY format of the server, but is there a way to switch it around to DMY?

    Thanks (smile)

  173. Where can I find a method to convert a JSON string to an ASP Dictionary object?

    • Sam, this class does not provide such functionality. It only generates JSON, but does not parse it.

      • I had to translate ’s json_parse.js into VBScript and integrate it into jsCore.

        It seems to work but I am still testing. Is this something I could submit back to you for your inclusion in jsCore?

        • no, not really

        • Hi Sam,

          Could you make it public, so we can test (and use ;-)) it?

  174. Two things:

    - I found two ASP libraries and couldn’t decide if either had stronger attributes. Both were very cleanly written and I didn’t choose JSON.asp for any reason I can point to. There seems to be more forum activity here, so perhaps I made the wrong choice.

    If you would like to see the library I’ve got which is fairly well tested now and offers full-duplex JSON on the server-side, let me know how to get it to you or otherwise post the library.

    Sam

    • Could you send me the JSON parser you translated? I am fairly new to ASP and am having one tough time trying to translate a javascript parser into vbscript! I would really appreciate it.

      Sean

  175. I could not get the first example to work until I added a false parameter to the end of the call:

    response.write ((new JSON).toJSON(“rows”, rs, false))

    Until then, I was getting a “Wrong Number of arguments” error.

  176. Pingback: Utilizando JSON no ASP « Mateus Gamba

  177. Pingback: Introdução ao JSON » klebermota.eti.br

  178. Pingback: JSON in 10 minute : IT GupShup.com

  179. Thanks dear Michal for the clas.

    could you please tell me how return a very simple result in asp :
    {{“server”: “good”,”message”: “Done”}

    I need to response.Write theresult,
    I dont want to use js.

    thanks

  180. Pingback: pligg.com

  181. json link include send me my mail plesa

  182. Pingback: JSON | 自由之心

  183. Pingback: JSON (JavaScript Object Notation) | Acordo Coletivo (Petroleiros, Bancários, Prof de Saúde)

  184. I love what you guys are up too. Such clever work and exposure!
    Keep up the awesome works guys I’ve included you guys to my own blogroll.