Warum ist der Indexer meiner .NET-Komponente nicht immer über VBScript zugänglich?

Ich habe eine .NET-Assembly, auf die ich über COM-Interop von VBScript (klassisches ASP) aus zugreifen kann. Eine Klasse hat einen Indexer (a.k.a. Standardeigenschaft), den ich mit VBScript erhalten habe, indem ich dem Indexer das folgende Attribut hinzufügte:[DispId(0)]. In den meisten Fällen funktioniert dies, jedoch nicht, wenn Sie als Mitglied eines anderen Objekts auf die Klasse zugreifen.

Wie kann ich dafür sorgen, dass es mit der folgenden Syntax funktioniert:Parent.Member("key") wo Member den Indexer hat (ähnlich wie beim Zugriff auf die Standardeigenschaft des eingebautenRequest.QueryString: Request.QueryString("key"))?

In meinem Fall gibt es eine ElternklasseTestRequest mit einerQueryString Eigenschaft, die ein @ zurückgiIRequestDictionary, das den Standardindexer hat.

VBScript Beispiel:

Dim testRequest, testQueryString
Set testRequest = Server.CreateObject("AspObjects.TestRequest")
Set testQueryString = testRequest.QueryString
testQueryString("key") = "value"

Die folgende Zeile verursacht einen Fehler, anstatt "Wert" zu drucken. Dies ist die Syntax, mit der ich arbeiten möchte:

Response.Write(testRequest.QueryString("key"))

Microsoft VBScript-Laufzeit (0x800A01C2)
Falsche Anzahl von Argumenten oder ungültige Eigenschaftszuweisung: 'QueryString'

Jedoch die folgenden Zeilentu fehlerfrei arbeiten und den erwarteten "Wert" ausgeben (beachten Sie, dass die erste Zeile auf den Standardindexer für eine temporäre Variable zugreift):

Response.Write(testQueryString("key"))
Response.Write(testRequest.QueryString.Item("key"))

Below sind die vereinfachten Schnittstellen und Klassen in C # 2.0. Sie wurden registriert überRegAsm.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; }
    }
}

Ich habe versucht, mit verschiedenen Optionen zu recherchieren und zu experimentieren, aber noch keine Lösung gefunden. Jede mögliche Hilfe würde geschätzt, um herauszufinden, warum dastestRequest.QueryString("key") Syntax funktioniert nicht und wie man es zum Laufen bringt.

Hinweis: Dies ist eine Fortsetzung vonVeröffentlichung der Indexer- / Standardeigenschaft über COM Interop.

Update: Hier ist einige der generierten IDLs aus der Typbibliothek (unter Verwendung von 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);
};

Antworten auf die Frage(12)

Ihre Antwort auf die Frage