Retrieve string array from COM object using Classic ASP
I have a .NET class which holds a simple array of strings avail开发者_如何学Goable via an accessor method, which looks like this;
namespace Foo.Bar {
[ComVisible(true)]
[Guid("642279A0-85D4-4c7a-AEF5-A9FAA4BE85E5")]
public class MyClass {
private string[] _myArray;
public MyClass() { }
public MyClass(string[] myArray) {
_myArray = myArray;
}
public string[] MyArray {
get { return _myArray; }
}
}
}
I consume this class using Classic ASP;
Dim foo
Set foo = Server.CreateObject("Foo.Bar.MyClass")
if IsArray(foo.MyArray) then Response.Write("IsArray") & "<br />"
Response.Write(typename(foo.MyArray)) & "<br />"
Response.Write(UBound(foo.MyArray)) & "<br />"
This results in;
IsArray
String()
1
However, when I try to access the contents of the array using;
Response.Write(foo.MyArray(0)) & "<br />"
I get;
Microsoft VBScript runtime (0x800A01C2) Wrong number of arguments or invalid property assignment: 'MyArray'
Any help is much appreciated.
Edit This is to provide more information after digesting the answers given (thanks)
When changing the implementation of the MyArray property to;
public object[] MyArray {
get { return (object[])_myArray; }
}
I then get the following error,
Microsoft VBScript runtime (0x800A000D) Type mismatch: 'MyArray'
So I tried individually casting each string to an object;
public object[] MyArray {
get {
object[] tmp = new object[_myArray.Count()];
for (int x = 0; x < _myArray.Count(); x++) {
tmp[x] = (object)_myArray[x];
}
return tmp;
}
}
Then I'm back to,
Microsoft VBScript runtime (0x800A01C2) Wrong number of arguments or invalid property assignment: 'MyArray'
Edit Final solution with help from How to correctly marshal VB-Script arrays to and from a COM component written in C#
C#
public object MyArray {
get { return _myArray.Cast<object>().ToArray(); }
}
VBScript
Dim foo
Set foo = Server.CreateObject("Foo.Bar.MyClass")
bar = foo.MyArray
Response.Write bar(0)
The key was to expose object
rather than object[]
and as AnthonyWJones suggested, assign the array to a variable before using it.
Thanks again.
The problem is VBScript cannot actually use an array of String
. It can only use an array of Variant
.
Try changing MyClass
to expose an object[]
instead.
In addition to Anthony's suggestion
I'm not sure is it the best way but in the past I used a code similar to the following to handle one dimensional arrays.
public object MyArray(int ix = -1){
string[] tmp = new string[] {"one", "two", "3", "4"};
return (ix == -1) ? (object)tmp : tmp[ix];
}
In ASP:
Response.Write(TypeName(foo.MyArray)) 'string()
Response.Write(TypeName(foo.MyArray(0))) 'string
VBScript doesn't understand generic collections such as List<string>
and it doesn't understand string arrays either.
I wrote a public function into my Interface class to convert any generic collections into an ArrayList
public ArrayList toArrayList(IEnumerable collection)
{
var arrayList = new ArrayList();
foreach (object element in collection)
{
arrayList.Add(element);
}
return arrayList;
}
This code can then be used in VBScript like this
dim connector
set connector = model.getRelationByID(connectorID)
'get the related elements
dim relatedElements
set relatedElements = model.toArrayList(connector.relatedElements)
addRelatedElementoAutoDiagram relatedElements(0), relatedElements(1), model
The advantage of this approach is that I don't need to change the signature of any of the methods or properties in C#, but I can still use them in VBScript
This code demonstrates how to handle arrays between COM and ASP:
<% @Language="VBScript" %>
<% Option Explicit %>
<%
Dim tcs
Dim rc
Dim vntInput(0,4)
Dim i
vntInput(0,0) = Request.QueryString("strUser")
vntInput(0,1) = Request.QueryString("intCreate")
vntInput(0,2) = Request.QueryString("intDelete")
vntInput(0,3) = Request.QueryString("intModify")
vntInput(0,4) = Request.QueryString("intView")
Set tcs = Server.CreateObject("TestCases.ArrayFailure")
rc = tcs.AcceptArray(vntInput)
For i = 0 to UBound(vntInput, 2)
Response.write "Loop Count " & i & " " & vntInput(0,i) & "<BR>"
Next
%>
Here's a link to the article where I found this code:
http://202.102.233.250/b2000/ASP/articles/component/pv990826.htm
精彩评论