PRB: Implements Keyword Fails In VB DLL Called From ASPID: Q188716
|
When calling a server side ActiveX component from an Active Server Pages (ASP) page that was written in Visual Basic 6.0 and uses the "Implements" keyword to get implementation inheritance between classes, the object does not expose the implemented methods as part of the interface. When you assign the derived object back to a base object, ASP will report the following error:
Microsoft VBScript runtime error '800a01b6' Object doesn't support this property or method.
VBScript is late-bound and can only QueryInterface for IDispatch, which simply returns the default IDispatch interface for the object. To get to an implemented interface you must QueryInterface for a specific interface. This is possible in Visual Basic for Applications, Visual Basic 4.0, and Visual Basic 5.0 because you can early-bind to type information and dimension object variables that expect a specific interface. When this is done Visual Basic will QueryInterface for an interface pointer of only this type in the variable. You will have the same problem in Visual Basic if you dimension the variables as Variants because Visual Basic will not save a specific interface and will QueryInterface for IDispatch, just like VBScript.
Visual Basic does not support inheritance, but there are workarounds for the problem. Look in the MORE INFORMATION section for details.
This behavior is by design.
The following sample demonstrates the differences between how Visual Basic
6.0 and Active Server Pages (ASP) handle inheritance. Following are two
workarounds showing how to simulate inheritance for ASP without the use of Microsoft Transaction Server (MTS). Finally, there is a workaround to simulate inheritance for MTS.
This example creates two classes. The first class, CPerson, supports the
FirstName and the LastName method. The second class, CEmployee, implements
CPerson and has a method GetName. From Visual Basic 6.0 the code sample
works with all methods available, but from an Active Server Page, the
FirstName and LastName methods are not available.
' Person class
Option Explicit
Public Property Get FirstName() As String
End Property
Public Property Get LastName() As String
End Property
Public Property Let LastName(sLastName As String)
End Property
Public Property Let FirstName(sFirstName As String)
End Property
' Employee class
Option Explicit
Implements CPerson
Private m_sFirstName As String
Private m_sLastName As String
Public Function GetEmployeeName() As String
GetEmployeeName = m_sFirstName & " " & m_sLastName
End Function
Private Property Let CPerson_FirstName(RHS As String)
m_sFirstName = RHS
End Property
Private Property Get CPerson_FirstName() As String
CPerson_FirstName = m_sFirstName
End Property
Private Property Let CPerson_LastName(RHS As String)
m_sLastName = RHS
End Property
Private Property Get CPerson_LastName() As String
CPerson_LastName = m_sLastName
End Property
Private Sub Form_Load()
Dim oPerson As People.CPerson
Dim oEmp As People.CEmployee
Set oEmp = CreateObject("People.CEmployee")
Set oPerson = oEmp
oPerson.FirstName = "Some"
oPerson.LastName = "Body"
Form1.Hide
MsgBox oEmp.GetEmployeeName
End Sub
Run the code. You should see a Message Box that displays the following:
Some Body
This is the behavior you would like to get from ASP but cannot. Use the
following steps to see how ASP handles the People.dll:
<%
Dim oPerson
Dim oEmp
Set oEmp = Server.CreateObject("People.CEmployee")
Set oPerson = oEmp
oPerson.FirstName = "Some"
oPerson.LastName = "Body"
Response.Write oEmp.GetEmployeeName
%>
Microsoft VBScript runtime error '800a01b6' Object doesn't support this property or method: 'FirstName' /xxx.asp, line 6
Public Property Get Person() As CPerson
Set Person = Me
End Property
<%
Dim oEmp
Dim oPerson
Set oEmp = Server.CreateObject("People.CEmployee")
Set oPerson = oEmp.Person
Response.Write TypeName (oPerson) & "<BR>"
oPerson.FirstName = "Some"
oPerson.LastName = "Body"
Response.write oEmp.GetEmployeeName
%>
CEmployee
Some Body
Where CEmployee is the typename returned from the oPerson object.
Public Property Get FirstName() As String
FirstName = CPerson_FirstName
End Property
Public Property Let FirstName(RHS As String)
m_sFirstName = RHS
End Property
Public Property Get LastName() As String
LastName = CPerson_LastName
End Property
Public Property Let LastName(RHS As String)
m_sLastName = RHS
End Property
<%
Dim oEmp
Set oEmp = Server.CreateObject("People.CEmployee")
oEmp.FirstName = "Some"
oEmp.LastName = "Body"
Response.write oEmp.GetEmployeeName
%>
Open the modified ASP page in your Web browser. You should see the
following:
Some Body
net stop iisadmin /y
net start w3svc
Microsoft Transaction Server Type Library
Public Property Get Person() As CPerson
Set Person = SafeRef(Me)
End Property
'1 - NoTransactions'
NOTE: This samples uses '1 - NoTransactions', but it should work similarly for the other MTSTransactionMode properties.
CEmployee
Some Body
where CEmployee is the typename returned from the oPerson object.
For more information on using the Implements feature of Visual Basic,
use the Visual Basic Help, and search on the keyword "Implements."
For additional information, click the article number below
to view the article in the Microsoft Knowledge Base:
Q223406 HOWTO: Create an Empty MTS Package to Add Components for ASP
Additional query words: kbnokeyword
Keywords : kbASP kbCOMt kbCtrl kbMTS200 kbVBp500 kbVBp600 kbVisID kbGrpASP
Version : winnt:2.0
Platform : winnt
Issue type : kbprb
Last Reviewed: July 28, 1999