Vb.net 从ASP到.NET COM的方法调用失败
背景: 我有一个用ASP(VBScript)编写的遗留应用程序,它调用用VB6编写的COM组件。我们正在分阶段升级,需要首先将COM组件更新到.NET,同时保持与ASP的互操作性 情况:Vb.net 从ASP到.NET COM的方法调用失败,vb.net,vbscript,asp-classic,com,vb6,Vb.net,Vbscript,Asp Classic,Com,Vb6,背景: 我有一个用ASP(VBScript)编写的遗留应用程序,它调用用VB6编写的COM组件。我们正在分阶段升级,需要首先将COM组件更新到.NET,同时保持与ASP的互操作性 情况: 我创建了一个示例.NET类,并根据MSDN文档使用各种属性将其公开给COM系统 我能够实例化这个类 我能够在类上调用所需的方法 问题: 参数值未发送到COM方法。e、 g.所有数值类型在方法内的值均为0;所有引用类型在方法中都有null值。文本字符串被正确地传递给方法。但是,不会传递字符串变量 返回值也存在同样
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
Public Class Class1
'Inherits ServicedComponent
'Implements IClass1
Public Sub New()
' needed for COM
End Sub
Private Const LogMessageFormat As String = "[{0:s}] Input: {1}, {2}" + vbCrLf
Public Function Triple(csinput As String, nInput As Integer) As Integer 'Implements IClass1.Triple
IO.File.AppendAllText("C:\TestCOM.Class1_Triple.log",
String.Format(LogMessageFormat, Date.Now, if(csinput isnot Nothing, csinput, "**NULL**"), nInput))
Return 97
End Function
End Class
dim testNETCOM
set testNETCOM = Server.CreateObject("TESTCOM.Class1")
' ** use this to check if there was any error during instantiation
If Err.Number <> 0 Then
Response.Redirect("http://"&Err.Description&"/")
'Response.Write (Err.Description& "<br><br>")
else
'Response.Redirect("http://no-error/")
End If
' ** use this to check if object is actually instantiated
if testNETCOM is nothing then
Response.Redirect("http://no-com/")
else
'Response.Redirect("http://yes-com/")
end if
dim nInput
set nInput = 41
dim nOutput
set nOutput = -1
set nOutput = CLng(testNETCOM.Triple("test message")) ' this string is received in the method
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this string is not received in the method
' ** use this to check if return value is what we expected
if nOutput <> 0 then
Response.Redirect("http://test/")
else
Response.Redirect("http://notest/") ''' **this happens**
end if
公共接口IClass1
函数三元组(ByVal输入为字符串)为整数
端接口
公共班级1
继承ServicedComponent
实现IClass1
公共分新()
"COM需要"
端接头
公共函数Triple(作为字符串输入)作为整数实现IClass1.Triple
IO.File.WriteAllText(“C:\TestCOM.Class1_Triple.log”,String.Format(“[{0:s}]Input:{1}”,Date.Now,Input))“”“此文件已更新;所以我知道方法正在被调用。
返回97
端函数
末级
备用COM代码
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
Public Class Class1
'Inherits ServicedComponent
'Implements IClass1
Public Sub New()
' needed for COM
End Sub
Private Const LogMessageFormat As String = "[{0:s}] Input: {1}, {2}" + vbCrLf
Public Function Triple(csinput As String, nInput As Integer) As Integer 'Implements IClass1.Triple
IO.File.AppendAllText("C:\TestCOM.Class1_Triple.log",
String.Format(LogMessageFormat, Date.Now, if(csinput isnot Nothing, csinput, "**NULL**"), nInput))
Return 97
End Function
End Class
dim testNETCOM
set testNETCOM = Server.CreateObject("TESTCOM.Class1")
' ** use this to check if there was any error during instantiation
If Err.Number <> 0 Then
Response.Redirect("http://"&Err.Description&"/")
'Response.Write (Err.Description& "<br><br>")
else
'Response.Redirect("http://no-error/")
End If
' ** use this to check if object is actually instantiated
if testNETCOM is nothing then
Response.Redirect("http://no-com/")
else
'Response.Redirect("http://yes-com/")
end if
dim nInput
set nInput = 41
dim nOutput
set nOutput = -1
set nOutput = CLng(testNETCOM.Triple("test message")) ' this string is received in the method
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this string is not received in the method
' ** use this to check if return value is what we expected
if nOutput <> 0 then
Response.Redirect("http://test/")
else
Response.Redirect("http://notest/") ''' **this happens**
end if
公共班级1
'继承ServicedComponent
'实现IClass1
公共分新()
"COM需要"
端接头
Private Const LogMessageFormat As String=“[{0:s}]输入:{1},{2}”+vbCrLf
公共函数Triple(csinput作为字符串,nInput作为整数)作为Integer'实现IClass1.Triple
IO.File.AppendAllText(“C:\TestCOM.Class1_Triple.log”,
Format(LogMessageFormat,Date.Now,if(csinput不是空的,csinput,**NULL**),nInput))
返回97
端函数
末级
ASP代码
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
Public Class Class1
'Inherits ServicedComponent
'Implements IClass1
Public Sub New()
' needed for COM
End Sub
Private Const LogMessageFormat As String = "[{0:s}] Input: {1}, {2}" + vbCrLf
Public Function Triple(csinput As String, nInput As Integer) As Integer 'Implements IClass1.Triple
IO.File.AppendAllText("C:\TestCOM.Class1_Triple.log",
String.Format(LogMessageFormat, Date.Now, if(csinput isnot Nothing, csinput, "**NULL**"), nInput))
Return 97
End Function
End Class
dim testNETCOM
set testNETCOM = Server.CreateObject("TESTCOM.Class1")
' ** use this to check if there was any error during instantiation
If Err.Number <> 0 Then
Response.Redirect("http://"&Err.Description&"/")
'Response.Write (Err.Description& "<br><br>")
else
'Response.Redirect("http://no-error/")
End If
' ** use this to check if object is actually instantiated
if testNETCOM is nothing then
Response.Redirect("http://no-com/")
else
'Response.Redirect("http://yes-com/")
end if
dim nInput
set nInput = 41
dim nOutput
set nOutput = -1
set nOutput = CLng(testNETCOM.Triple("test message")) ' this string is received in the method
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this string is not received in the method
' ** use this to check if return value is what we expected
if nOutput <> 0 then
Response.Redirect("http://test/")
else
Response.Redirect("http://notest/") ''' **this happens**
end if
dim testNETCOM
设置testNETCOM=Server.CreateObject(“TESTCOM.Class1”)
'**使用此选项检查实例化过程中是否存在任何错误
如果错误号为0,则
重定向(“http://”和Err.Description&“/”)
'Response.Write(错误描述&“
”)
其他的
'响应。重定向('http://no-error/")
如果结束
“**使用此选项检查对象是否实际实例化
如果testNETCOM什么都不是,那么
响应。重定向(“http://no-com/")
其他的
'响应。重定向('http://yes-com/")
如果结束
暗忍者
设置nInput=41
暗淡的努特
设置nOutput=-1
set nOutput=CLng(testNETCOM.Triple(“test message”)”此字符串在方法中接收
set nOutput=CLng(testNETCOM.Triple(CStr(nInput))”方法中未收到此字符串
“**使用此选项检查返回值是否符合我们的预期
如果nOutput为0,则
响应。重定向(“http://test/")
其他的
响应。重定向(“http://notest/“”“”**这种情况会发生**
如果结束
尝试以下两种方法之一:
<ComVisible(True)>
<Guid("79571A9D-2345-48D9-8F86-7F6761A97DBA")>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<Guid("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
公共接口IClass1
函数三元组(ByVal输入为字符串)为整数
端接口
公共班级1
继承ServicedComponent
实现IClass1
公共分新()
"COM需要"
端接头
公共函数Triple(作为字符串输入)作为整数实现IClass1.Triple
IO.File.WriteAllText(“C:\TestCOM.Class1_Triple.log”,String.Format(“[{0:s}]Input:{1}”,Date.Now,Input))“”“此文件已更新;所以我知道方法正在被调用。
返回97
端函数
末级
或:
公共班级1
'继承ServicedComponent
'实现IClass1
公共分新()
"COM需要"
端接头
Private Const LogMessageFormat As String=“[{0:s}]输入:{1},{2}”+vbCrLf
公共函数Triple(csinput作为字符串,nInput作为整数)作为Integer'实现IClass1.Triple
IO.File.AppendAllText(“C:\TestCOM.Class1_Triple.log”,
Format(LogMessageFormat,Date.Now,if(csinput不是空的,csinput,**NULL**),nInput))
返回97
端函数
末级
问题在于ASP.NET的语法
set nInput = 41 ' this is wrong
nInput = 41 ' this is right
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this is wrong
nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this is right
请注意,VB6长类型是.Net类型System.Int32或VB类型Integer。此外,VB.Net编译器将帮助您创建COM类,而无需在将应用程序应用于该类时手工制作接口。关于不同的数据类型,这一点很好。我更新了代码,但问题仍然存在。我的主要目的是让编译器处理向COM公开类的问题,因为我比我自己更相信这一点。无论如何,我认为您需要做的就是为类和接口应用一个惟一的属性。为此,请使用VS工具使其变得简单。工具菜单->创建GUID->选择格式6(VS 2013下)->复制。然后粘贴到类上,对接口重复。也尝试了。运气不好:(我提出并编辑了以下问题:文字值的传递很好。变量出错。这适用于字符串和整数。我不知道问题出在哪里。我已经创建了您的COM类,并且能够从VBS和Excel VBA成功地使用它。我不做ASP。我建议您更新代码以显示包含GUID属性。祝你好运。还是不走运。正在尝试其他一些选项以获取更多信息