Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ASP.NET MVC know that a method is an action method?

Tags:

asp.net-mvc

I'm trying to write a unit test that will loop through all action methods on my controller classes looking for action methods that don't have some security-related attribute on them (e.g. [Authorize]).

How does the ASP.NET routing engine determine which methods are action methods? Obviously the action methods have to be public, but methods like ToString() are not action methods, so there is some logic to this.

like image 306
Jon Kruger Avatar asked Jul 06 '09 13:07

Jon Kruger


People also ask

What is action method in ASP.NET MVC?

ASP.NET MVC Action Methods are responsible to execute requests and generate responses to it. By default, it generates a response in the form of ActionResult. Actions typically have a one-to-one mapping with user interactions.

How is action method linked to the view?

The following illustrates the Index() action method in the StudentController class. As you can see in the above figure, the Index() method is public, and it returns the ActionResult using the View() method. The View() method is defined in the Controller base class, which returns the appropriate ActionResult .

What is action result method in MVC?

A controller action returns something called an action result. An action result is what a controller action returns in response to a browser request. The ASP.NET MVC framework supports several types of action results including: ViewResult - Represents HTML and markup.


2 Answers

All methods in a controller are considered Actions, except for non-public methods.

First, methods are matched by name: MethodName = ActionName.

If you want to override the default behavior, you use [ActionName] attribute.

public MyController
{
    [ActionName("ActionY")]
    public MethodX ()
    {
    }
}

Then this method will fire when a http://..../ActionY url is requested.

Read more in Phil's blog: How a Method Becomes An Action

EDIT: Okay, maybe this one: All public methods defined directly in your controller class, not inherited from base classes, not overriding those in base classes, unless you recursively identified those base methods to be actions already, not decorated with NoAction attribute.

like image 134
User Avatar answered Oct 02 '22 10:10

User


I stopped being lazy and I found the answer, most of which was in System.Web.Mvc.ActionMethodSelector.PopulateLookupTables() (thanks Reflector!)

    private IEnumerable<MethodInfo> GetActionMethods(Type controllerType)
    {
        return Array.FindAll(controllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance), IsValidActionMethod);
    }

    private static bool IsValidActionMethod(MethodInfo methodInfo)
    {
        return (!methodInfo.IsSpecialName && !methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(Controller)) && 
            !methodInfo.GetCustomAttributes(typeof(NonActionAttribute), true).Any());
    }

I was surprised to see all of the public methods on my base controller classes that were exposed with no security on them!

like image 37
Jon Kruger Avatar answered Oct 02 '22 09:10

Jon Kruger