I have a .NET assembly which I am accessing from VBScript (classic ASP) via COM interop. One class has an indexer (a.k.a. default property) which I got working from VBScript by adding the following attribute to the indexer: [DispId(0)]
. It works in most cases, but not when accessing the class as a member of another object.
How can I get it to work with the following syntax: Parent.Member("key")
where Member has the indexer (similar to accessing the default property of the built-in Request.QueryString
: Request.QueryString("key")
)?
In my case, there is a parent class TestRequest
with a QueryString
property which returns an IRequestDictionary
, which has the default indexer.
VBScript example:
Dim testRequest, testQueryString
Set testRequest = Server.CreateObject("AspObjects.TestRequest")
Set testQueryString = testRequest.QueryString
testQueryString("key") = "value"
The following line causes an error instead of printing "value". This is the syntax I would like to get working:
Response.Write(testRequest.QueryString("key"))
Microsoft VBScript runtime (0x800A01C2)
Wrong number of arguments or invalid property assignment: 'QueryString'
However, the following lines do work without error and output the expected "value" (note that the first line accesses the default indexer on a temporary variable):
Response.Write(testQueryString("key"))
Response.Write(testRequest.QueryString.Item("key"))
Below are the simplified interfaces and classes in C# 2.0. They have been registered via RegAsm.exe /path/to/AspObjects.dll /codebase /tlb
:
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRequest {
IRequestDictionary QueryString { get; }
}
[ClassInterface(ClassInterfaceType.None)]
public class TestRequest : IRequest {
private IRequestDictionary _queryString = new RequestDictionary();
public IRequestDictionary QueryString {
get { return _queryString; }
}
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRequestDictionary : IEnumerable {
[DispId(0)]
object this[object key] {
[DispId(0)] get;
[DispId(0)] set;
}
}
[ClassInterface(ClassInterfaceType.None)]
public class RequestDictionary : IRequestDictionary {
private Hashtable _dictionary = new Hashtable();
public object this[object key] {
get { return _dictionary[key]; }
set { _dictionary[key] = value; }
}
}
I've tried researching and experimenting with various options but have not yet found a solution. Any help would be appreciated to figure out why the testRequest.QueryString("key")
syntax is not working and how to get it working.
Note: This is a followup to Exposing the indexer / default property via COM Interop.
Update: Here is some the generated IDL from the type library (using oleview):
[
uuid(C6EDF8BC-6C8B-3AB2-92AA-BBF4D29C376E),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AspObjects.IRequest)
]
dispinterface IRequest {
properties:
methods:
[id(0x60020000), propget]
IRequestDictionary* QueryString();
};
[
uuid(8A494CF3-1D9E-35AE-AFA7-E7B200465426),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AspObjects.IRequestDictionary)
]
dispinterface IRequestDictionary {
properties:
methods:
[id(00000000), propget]
VARIANT Item([in] VARIANT key);
[id(00000000), propputref]
void Item(
[in] VARIANT key,
[in] VARIANT rhs);
};