使用经典 ASP 从 COM 对象检索字符串数组

发布于 2024-12-09 13:20:49 字数 2377 浏览 0 评论 0原文

我有一个 .NET 类,它包含通过访问器方法可用的简单字符串数组,如下所示;

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; }
        }
    }
}

我使用 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 />"

这导致;

IsArray
String()
1

但是,当我尝试使用以下方式访问数组的内容时:

Response.Write(foo.MyArray(0)) & "<br />"

我明白了;

Microsoft VBScript 运行时 (0x800A01C2) 参数数量错误或 无效的属性分配:'MyArray'

非常感谢任何帮助。

编辑 这是为了在消化给出的答案后提供更多信息(谢谢)

当将 MyArray 属性的实现更改为时;

public object[] MyArray {
    get { return (object[])_myArray; }
}

然后我收到以下错误,

Microsoft VBScript 运行时 (0x800A000D) 类型不匹配:“MyArray”

因此我尝试将每个字符串单独转换为一个对象;

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;
    }
}

然后我又回到了,

Microsoft VBScript 运行时 (0x800A01C2) 参数数量错误或 无效的属性分配:'MyArray'

编辑如何正确地将 VB 脚本数组编组到用 COM 编写的组件或从 COM 组件中编组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)

关键是公开 object 而不是 object[] ,正如 AnthonyWJones 所建议的那样,在使用数组之前将其分配给变量。

再次感谢。

I have a .NET class which holds a simple array of strings available 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春花秋月 2024-12-16 13:20:49

问题是 VBScript 实际上无法使用 String 数组。它只能使用Variant数组。

尝试更改 MyClass 以公开 object[]

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.

请远离我 2024-12-16 13:20:49

除了安东尼的建议

我不确定这是否是最好的方法,但在过去我使用类似于以下的代码来处理一维数组。

public object MyArray(int ix = -1){
    string[] tmp = new string[] {"one", "two", "3", "4"};
    return (ix == -1) ? (object)tmp : tmp[ix];
}

<在 ASP 中:

Response.Write(TypeName(foo.MyArray)) 'string()
Response.Write(TypeName(foo.MyArray(0))) 'string

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
寄人书 2024-12-16 13:20:49

VBScript 不理解诸如 List 之类的通用集合,也不理解字符串数组。

我在 Interface 类中编写了一个公共函数,以将任何通用集合转换为 ArrayList

public ArrayList toArrayList(IEnumerable collection)
{
        var arrayList = new ArrayList();
        foreach (object element in collection)
        {
            arrayList.Add(element);
        }
        return arrayList;
}

然后可以在 VBScript 中使用此代码,如下所示

 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

这种方法的优点是我不需要更改任何方法或属性的签名在 C# 中,但我仍然可以在 VBScript 中使用它们

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

我是有多爱你 2024-12-16 13:20:49

此代码演示了如何处理 COM 和 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

%>

这是我在其中找到此代码的文章的链接:
http://202.102.233.250/b2000/ASP/articles/component/pv990826.htm

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文