HOWTO: Convert between JScript Array and VB Safe Array


I recently got a question about how to manipulate the LIST data type within JScript since my sample code only illustrated VBScript.


Well… one reason why that example is in VBScript is because LIST manipulation (a VB SafeArray) is more straight forward and requires much less code in VBScript.


Then, there is Microsoft documentation which says the following time and again (and echo’d in lots of other places):



There is currently no way to convert a JavaScript array into a VBArray


Really? I could not believe it. A quick search of the Internet turned up no results of how to do this, either… so it sounds like a good challenge to me. :-)


I racked my brain a little, and I came up with the following built-in solution to the problem of converting a JScript array into a VB SafeArray. Yes, I know it is not efficient, but for casual conversion for the purposes of IIS configuration, it definitely suffices. And it works on Windows 2000 on up with no additional requirements, a definite bonus from a dependency/ubiquity point-of-view.


See the following JScript code which manipulates the IIS ScriptMaps property (a VB SafeArray) by first converting the SafeArray into JScript array, then manipulating it in JScript, and finally converting it back to a VB SafeArray for use by the Scriptmaps LIST property.


Enjoy!


//David

var objRoot = GetObject( “IIS://localhost/w3svc/1/root” );
var arrVB = objRoot.Get( “ScriptMaps” );

//
// Convert from VB Array for manipulation in JScript
//
var arrJS = VB2JSArray( arrVB );
//
// Insert a test Value at end of ScriptMaps
//
arrJS[ arrJS.length ] = “.test,value,0”;
//
// Convert back to VB Array to save by IIS
//
objRoot.ScriptMaps = JS2VBArray( arrJS );
objRoot.SetInfo();

function VB2JSArray( objVBArray )
{
return new VBArray( objVBArray ).toArray();
}

function JS2VBArray( objJSArray )
{
var dictionary = new ActiveXObject( “Scripting.Dictionary” );
for ( var i = 0; i < objJSArray.length; i++ )
{
dictionary.add( i, objJSArray[ i ] );
}

return dictionary.Items();
}

Comments (12)

  1. Mert Sakarya says:

    David,

    Thank you very much for this post. This was exactly what I was looking for. Even the IIS property is the same. 😉

  2. David.Wang says:

    Mert – hmm… I wonder who the question came from! 😉

    //David

  3. Duane Roelands says:

    This is pretty neat; I only wish it worked for two-dimensional arrays.

  4. David.Wang says:

    Duane – Well, JScript does not have the idea of a multi-dimensional array, but is that really a problem? Outside of math, I really think that Objects and References are better solutions to address the need to efficient associate data and the memory that it contains.

    I suggest converting/revising your code as necessary.

    I used to love multi-dimensional arrays when I started with VB, but as soon as I learned pointers, references, and memory management, I immediately saw that multi-dimensional arrays are rarely good.

    //David

  5. Solfrid says:

    Hello, I was wondering if you could offer your advice on a specific instance of the problem described in this post.

    I read that the output of a Request.BinaryRead call is a VB Safearray. However when I try the technique illustrated above, which should theoretically work, I get a "VBArray expected" error. Does this make any sense to you?

  6. Eiríkur Fannar Torfason says:

    David, today you’re my hero.

    I’m currently in the process of updating an installer for a product of ours that has been migrated from ASP.NET 1.1 to ASP.NET 2.0. The installer just happens to use JScript to set up the VDirs needed and thanks to this post here, I’m now able to correctly set the scriptmaps for ASP.NET 2.0. And don’t worry, I also read another post of yours which mentioned that you can’t have two web apps using separate versions of ASP.NET in the same app pool so I’ll modify the installer to create a separate app pool just for our product.

  7. Jim Dippner says:

    David,

    Thanks for your post, this helped me out with some ADSI/WMI scripting that I was doing.  Most scripting examples are provided in VBScript, but I prefer to use JS for the try/catch exception handling.

    I do recommend an enhancement to the VB2JSArray function.  In some cases, if the returned array is a single value, the JScript interpreter does not recognize it as an array and raises a "VBArray Expected" exception.  A quick fix to this is as follows:

    function VB2JSArray( objVBArray )

    {

    var a;

       // return new VBArray( objVBArray ).toArray();

    try{

    a = new VBArray( objVBArray ).toArray();

    }

    catch(e){

    a = new Array(objVBArray);

    }

    return a;

    }

  8. iJoost says:

    Well, its not pretty but this seems to work. I found this as VBScript and just tried what would happen if I simply translated it to JavaScript. Worked for me. I’m looking at the data I wanted now. :-)    var

    strDataWhole=”;

    //Get binary data from form        

       var noBytes = Request.TotalBytes;

       var binData = Request.BinaryRead(noBytes);

    //Convert binary data to a string

       var RST=Server.CreateObject(‘ADODB.Recordset’);

       var LenBinary=noBytes;

       var adLongVarChar=201;

       if(0<LenBinary){

         RST.Fields.Append(‘myBinary’,adLongVarChar,LenBinary);

         RST.Open();

         RST.AddNew();

         RST(‘myBinary’).AppendChunk(binData);

         RST.Update();

         strDataWhole=RST(‘myBinary’);

       }

  9. Rasberry says:

    This is pretty cool. I think I was looking at creating an ASPI filter to do this, but now I can do it from JScript directly.

    Thanks!!

    var byteCount = Request.TotalBytes;

    var binaryString = null;

    if (byteCount > 0)

    {

    var binary = Request.BinaryRead(byteCount)

    var rst = Server.CreateObject(‘ADODB.Recordset’);

    rst.Fields.Append(‘myBinary’,201,byteCount);

    rst.Open();

    rst.AddNew();

    rst(‘myBinary’).AppendChunk(binary);

    rst.update();

    binaryString = rst(‘myBinary’);

    }

  10. trevise says:

    Does any one knows if this will work to convert a JScript Array() to a C# List<t> ?

  11. marmaladiator says:

    Thanks for this! I was seriously stuck interrogating a ‘ADODB.Recordset’ object to get AD account descriptions.

  12. Black Bart says:

    The following code converts a multi-dimensional VB safe-array to a javascript multi-dimensional array.

    dumpsite.com/…/index.php