2017-02-16 14 views
1

фон:Метод вызова из ASP .NET в COM не удается

У меня есть устаревшие приложения, написанные на ASP (VBScript), который называют COM-компоненты, написанные в VB6. Мы обновляемся поэтапно и должны сначала обновить COM-компоненты до .NET, поддерживая совместимость с ASP.

Ситуация:

  1. Я создал образец класса .NET и подвергал его COM системы, используя различные атрибуты согласно документации MSDN
  2. Я могу создать экземпляр класса
  3. Я могу чтобы вызвать нужный метод на классе

Проблема:

  1. Значения аргументов не отправляются методу COM. например все числовые типы имеют значение 0 внутри метода; все ссылочные типы имеют нулевое значение внутри метода. Литеральные строки передаются правильно методу. Однако строковые переменные не передаются.
  2. Такая же проблема с возвращаемым значением. Независимо от значения, возвращаемого методом, переменная ASP имеет значение по умолчанию (0 или null в зависимости от ситуации).

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 

Alternate COM код

<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 

ASP код

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 
+0

Опасайтесь, что тип VB6 Long .Net Тип System.Int32 или VB Integer. Кроме того, компилятор VB.Net поможет вам создать свой COM-класс, не требуя создания интерфейсов, если вы примените [ComClassAttribute] (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.comclassattribute (v = vs.110) .aspx # Примеры) для класса. – TnTinMn

+0

Хороший вопрос о разных типах данных.Однако я обновил код, проблема остается. – bigbyte

+0

Моей главной задачей было дать возможность компилятору разоблачить ваш класс в COM, поскольку я верю, что больше, чем я, с этим материалом. В любом случае, я думаю, что все, что вам нужно сделать, это применить уникальный атрибут для вашего класса, а также интерфейс. Используйте VS-инструмент для этого, чтобы сделать его простым. Инструменты Меню-> Создать GUID-> выбрать формат 6 (под VS 2013) -> копировать. Затем вставьте в класс, повторите для интерфейса. – TnTinMn

ответ

0

Дайте либо из них попробовать:

<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 

Или:

<ComVisible(True)> 
<ProgId("TESTCOM.Class1")> 
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3", "79571A9D-2345-48D9-8F86-7F6761A97DBA")> 
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 
+0

По-прежнему не повезло, попробовав несколько других вариантов, чтобы выловить больше информации – bigbyte

2

Проблема заключается в синтаксисе на ASP

  1. Для простых типов данных, не используйте 'набор'
  2. Для объектов, которые используют 'комплект'

Поскольку я использовал набор для простых типов, во время процесса присваивания была ошибка, а значение переменной для null/nothing/empty.

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 
Смежные вопросы