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
Anonymous
July 04, 2006
David,
Thank you very much for this post. This was exactly what I was looking for. Even the IIS property is the same. ;)Anonymous
July 04, 2006
Mert - hmm... I wonder who the question came from! ;-)
//DavidAnonymous
July 28, 2006
This is pretty neat; I only wish it worked for two-dimensional arrays.Anonymous
July 28, 2006
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.
//DavidAnonymous
September 07, 2007
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?Anonymous
October 23, 2007
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.Anonymous
February 21, 2008
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; }Anonymous
March 23, 2008
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'); }Anonymous
May 19, 2008
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'); }Anonymous
September 23, 2009
Does any one knows if this will work to convert a JScript Array() to a C# List<t> ?Anonymous
October 09, 2009
Thanks for this! I was seriously stuck interrogating a 'ADODB.Recordset' object to get AD account descriptions.Anonymous
July 02, 2012
The following code converts a multi-dimensional VB safe-array to a javascript multi-dimensional array. dumpsite.com/.../index.php