2009-07-06 22 views
8

Estoy intentando escribir una prueba unitaria que recorra todos los métodos de acción en mis clases de controlador buscando métodos de acción que no tengan algún atributo relacionado con la seguridad (por ejemplo, [Autorizar]).¿Cómo sabe ASP.NET MVC que un método es un método de acción?

¿Cómo determina el motor de enrutamiento de ASP.NET qué métodos son métodos de acción? Obviamente, los métodos de acción tienen que ser públicos, pero los métodos como ToString() no son métodos de acción, por lo que hay algo de lógica en esto.

Respuesta

1

que dejó de ser perezoso y he encontrado la respuesta, la mayoría de los cuales estaba en System.Web.Mvc.ActionMethodSelector.PopulateLookupTables() (gracias 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()); 
    } 

Me sorprendió ver toda la ¡métodos públicos en mis clases de controlador de base que se expusieron sin seguridad en ellos!

+1

Si necesita todos sus métodos de acción en un controlador para tener el filtro [Autorizar] en ellos, estoy bastante seguro de que podría simplemente agregarlo a la parte superior del controlador. Tiene el mismo efecto que agregarlo a cada acción.No creo que afecte los métodos de no acción, pero podría estar equivocado al respecto. –

8

Todos los métodos en un controlador se consideran acciones, excepto para los métodos no públicos.

En primer lugar, los métodos se relacionan por nombre: MethodName = ActionName.

Si desea anular el comportamiento predeterminado, use el atributo [ActionName].

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

A continuación, este método se disparará cuando se solicita una URL http://..../ActionY.

Leer más en el blog de Phil: How a Method Becomes An Action

EDIT: Bueno, tal vez éste: Todos los métodos públicos definidos directamente en su clase controlador, no se heredan de las clases de base, no anulando los de las clases base, a menos que recurrentemente identificado esos métodos base ya son acciones, no están decoradas con el atributo NoAction.

+1

"Todos los métodos en un controlador se consideran acciones, a excepción de que no sea pública métodos ". - No es cierto, ToString() es un método público, pero no es un método de acción. –

+0

Para agregar a esto, también puede agregar un atributo [NonAction] a un método público si necesita que sea público para propósitos de pruebas de unidades. –

+0

Está bien, obviamente ese no es, pero tienes la idea general. Usted hereda de la clase de controlador y qué métodos públicos definirá se convertirán en sus acciones. – User

1

Hay una muy buena explicación de cómo se procesan los métodos de acción en el libro de ASP.NET MVC que estoy usando como referencia. Como suele suceder, las páginas relevantes están disponibles en los libros de Google:

http://books.google.com/books?id=Xb3a1xTSfZgC&lpg=PA308&ots=J9GgXhsads&dq=action%20method%20selection%20sanderson&pg=PA310

En caso de que el enlace muere, es Página 310 de Pro ASP.NET MVC Framework por Steven Sanderson.

No estoy seguro de que le ayudará a encontrar la manera de escribir las pruebas unitarias, pero podría ayudarle a seguir el código del reflector ...

+0

¡Es un excelente artículo! ¡Gracias! –

Cuestiones relacionadas