开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜