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.
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.
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 .
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With