Calling dynamically named method?

Hi all,

How do I call a method whose name is determined dynamically via a users action? I am in the process of converting an APS web app to ASP .NET and am getting errors for the following (old ASP) statement:

somefunction = "Menu" & returnedAction & "Top()"
Execute(somefunction)

What is the ASP .NET equivalent? I have found there is an object type called 'DynamicMethod', however this is only in .NET Framework 2.0.

TIA

Comments

  • You can use the Visual Basic CallByName function, which is process intensive. Looking at the disassembly for this function, I see that their is alot of code that goes into making this function work. However, it is a quick solution. I also wrote a function below that uses reflection ...

    [code]
    Public Function Execute(ByVal obj As Object, ByVal funcName As String, ByVal params() As Object) As Object
    Dim t As Type = obj.GetType()
    Dim m As MethodInfo

    If params Is Nothing Then
    m = t.GetMethod(funcName, Type.EmptyTypes)
    Else
    Dim pTypes(params.Length - 1) As Type

    For i As Integer = 0 To params.GetUpperBound(0)
    pTypes(i) = params(i).GetType()
    Next

    m = t.GetMethod(funcName, pTypes)
    End If

    Return m.Invoke(obj, params)
    End Function
    [/code]

    Make sure to import the System.Reflection namespace. Below is a demo class and some example usages. You should be able to adapt it to your own scenario.

    [code]
    Public Class MyDemoClass
    Public Sub SomeFuncA()
    MsgBox("A")
    End Sub

    Public Sub SomeFuncB()
    MsgBox("B")
    End Sub

    Public Sub SomeFuncC(ByVal arg As String)
    MsgBox("C = " & arg)
    End Sub
    End Class

    ...
    Dim o As New MyDemoClass

    Execute(o, "SomeFuncA", Nothing)
    Execute(o, "SomeFuncB", Nothing)
    Execute(o, "SomeFuncC", New Object() {"Test"})

    [/code]

    Seeing how you prob. are calling functions within a form class, you can make calls like so ....

    [code]
    Execute(Me, "Menu" & returnedAction & "Top()", Nothing)
    [/code]
  • "... You can use the Visual Basic CallByName function, which is process intensive. Looking at the disassembly for this function, I see that their is alot of code that goes into making this function work. However, it is a quick solution. I also wrote a function below that uses reflection ...

    : [code]
    : Execute(Me, "Menu" & returnedAction & "Top()", Nothing)
    : [/code]
    :
    ..."

    Many Thanks, will give it a go!
  • Ok, I gave it a go but I have some issues.
    I am using the following to call:

    [code]
    somefunction= "Menu" & returnedAction & "Top()"
    varExecute(Me, somefunction, Nothing )[/code]

    Which calls:

    [code]
    Public Function VarExecute(ByVal obj As Object, ByVal funcName As String, ByVal params() As Object) As Object
    Dim t As Type = obj.GetType()
    Dim m As MethodInfo

    If params Is Nothing Then
    m = t.GetMethod(funcName, Type.EmptyTypes)
    Else
    Dim pTypes(params.Length - 1) As Type

    For i As Integer = 0 To params.GetUpperBound(0)
    pTypes(i) = params(i).GetType()
    Next

    m = t.GetMethod(funcName, pTypes)
    End If

    Return m.Invoke(obj, params)
    End Function
    [/code]

    However I am getting the following error (in IE):

    [code]
    Object reference not set to an instance of an object.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error:


    Line 660: End If
    Line 661:
    Line 662: Return m.Invoke(obj, params)
    Line 663: End Function
    Line 664:

    Stack trace:
    NullReferenceException: Object reference not set to an instance of an object.]
    ASP.Test_aspx.VarExecute(Object obj, String funcName, Object[] params) in c:.....aspx:662
    ASP.Test_aspx.Paint(Object area) in ....
    [/code]
  • [b][red]This message was edited by iwilld0it at 2006-7-20 6:37:3[/red][/b][hr]
    [b][red]This message was edited by iwilld0it at 2006-7-20 6:35:55[/red][/b][hr]
    The null exception is ocurring because it is not finding the function in the object (The form object in this case.) When I wrote the first function, I forgot to take private functions into consideration, so here is the modified function.

    [code]
    Public Function Execute(ByVal obj As Object, ByVal funcName As String, ByVal params() As Object) As Object
    Dim t As Type = obj.GetType()

    ' NOTE: This should handle any kind of function.
    Dim m As MethodInfo = t.GetMethod(funcName, _
    BindingFlags.Instance Or _
    BindingFlags.NonPublic Or _
    BindingFlags.Public Or _
    BindingFlags.Static Or _
    BindingFlags.FlattenHierarchy Or _
    BindingFlags.IgnoreCase)

    ' NOTE: What if method still not found?
    If m Is Nothing Then
    Throw New MissingMethodException(funcName)
    End If

    ' NOTE: Dynamically call the function.
    Return m.Invoke(obj, params)
    End Function
    [/code]

    The key to this new function is the BindingFlags argument.

    Note: Static means Shared functions and FlattenHierarchy means to look down the inheritence chain for static functions.

    W/ this said, you should be able to execute any function on the fly. The BindingFlags.NonPublic is what fixes the problem, because I bet you the functions you are trying to call are private.

    Cheers

    : Ok, I gave it a go but I have some issues.
    : I am using the following to call:
    :
    : [code]
    : somefunction= "Menu" & returnedAction & "Top()"
    : varExecute(Me, somefunction, Nothing )[/code]
    :
    : Which calls:
    :
    : [code]
    : Public Function VarExecute(ByVal obj As Object, ByVal funcName As String, ByVal params() As Object) As Object
    : Dim t As Type = obj.GetType()
    : Dim m As MethodInfo
    :
    : If params Is Nothing Then
    : m = t.GetMethod(funcName, Type.EmptyTypes)
    : Else
    : Dim pTypes(params.Length - 1) As Type
    :
    : For i As Integer = 0 To params.GetUpperBound(0)
    : pTypes(i) = params(i).GetType()
    : Next
    :
    : m = t.GetMethod(funcName, pTypes)
    : End If
    :
    : Return m.Invoke(obj, params)
    : End Function
    : [/code]
    :
    : However I am getting the following error (in IE):
    :
    : [code]
    : Object reference not set to an instance of an object.
    : Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
    :
    : Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
    :
    : Source Error:
    :
    :
    : Line 660: End If
    : Line 661:
    : Line 662: Return m.Invoke(obj, params)
    : Line 663: End Function
    : Line 664:
    :
    : Stack trace:
    : NullReferenceException: Object reference not set to an instance of an object.]
    : ASP.Test_aspx.VarExecute(Object obj, String funcName, Object[] params) in c:.....aspx:662
    : ASP.Test_aspx.Paint(Object area) in ....
    : [/code]
    :





  • Much appreciated iwilld0it, unfortunately I am still getting the same error. The 'funcname' is being passed through ok as is the object, but 'm' is still equating to nothing [code] Dim m As MethodInfo = t.GetMethod(funcName, _
    BindingFlags.Instance Or _
    BindingFlags.NonPublic Or _
    BindingFlags.Public Or _
    BindingFlags.Static Or _
    BindingFlags.FlattenHierarchy Or _
    BindingFlags.IgnoreCase)[/code].

    I think I need to go back and rework the structure of the code as I believe this is what is at fault. I have used the Microsoft migration tool which ended up with an ASP front page which uses a for the primary functions, to which it also 'includes' about another 8 include (aspx) files with functions resulting in response.write commands to formulate a dynamic html page. front_page.aspx includes initial.aspx, which then includes the rest.

    font_page.aspx
    --> Include initial.aspx
    --> menu.aspx
    --> Header.aspx
    --> Glob.aspx (Where the func you suggested is stored)
    --> Func.aspx (The location of the procedure that should be called)

    Many thanks in your effort!
  • Glad to help ... I wonder if it is a scoping issue ... try this ... hardcode a call to a function your trying to reach in the same spot your trying to use the Execute function. If the function call is not found, then you know it's a scoping issue, otherwise the function I provided just does not work for your scenario.

    : Much appreciated iwilld0it, unfortunately I am still getting the same error. The 'funcname' is being passed through ok as is the object, but 'm' is still equating to nothing [code] Dim m As MethodInfo = t.GetMethod(funcName, _
    : BindingFlags.Instance Or _
    : BindingFlags.NonPublic Or _
    : BindingFlags.Public Or _
    : BindingFlags.Static Or _
    : BindingFlags.FlattenHierarchy Or _
    : BindingFlags.IgnoreCase)[/code].
    :
    : I think I need to go back and rework the structure of the code as I believe this is what is at fault. I have used the Microsoft migration tool which ended up with an ASP front page which uses a for the primary functions, to which it also 'includes' about another 8 include (aspx) files with functions resulting in response.write commands to formulate a dynamic html page. front_page.aspx includes initial.aspx, which then includes the rest.
    :
    : font_page.aspx
    : --> Include initial.aspx
    : --> menu.aspx
    : --> Header.aspx
    : --> Glob.aspx (Where the func you suggested is stored)
    : --> Func.aspx (The location of the procedure that should be called)
    :
    : Many thanks in your effort!
    :

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories