我正在尝试编写一个单元测试,它将遍历我的控制器类上的所有操作方法,寻找不具有某些安全相关属性的操作方法(例如[Authorize])。
ASP.NET路由引擎如何确定哪些方法是操作方法?显然,动作方法必须是公共的,但像ToString()这样的方法不是动作方法,因此有一些逻辑。
答案 0 :(得分:8)
控制器中的所有方法都被视为操作,非公共方法除外。
首先,方法按名称匹配:MethodName = ActionName。
如果要覆盖默认行为,请使用[ActionName]属性。
public MyController
{
[ActionName("ActionY")]
public MethodX ()
{
}
}
然后,当请求http://..../ActionY网址时,此方法将会触发。
阅读Phil的博客:How a Method Becomes An Action
编辑:好的,也许这一个:直接在你的控制器类中定义的所有公共方法,不是从基类继承,而不是覆盖基类中的那些,除非你递归地将那些基本方法识别为已经被动作,而不是用NoAction修饰属性。答案 1 :(得分:1)
我不再懒惰,我找到了答案,其中大部分是在System.Web.Mvc.ActionMethodSelector.PopulateLookupTables()中(感谢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());
}
我很惊讶地发现我的基本控制器类上的所有公共方法都暴露在它们没有安全性的情况下!
答案 2 :(得分:1)
对于我正在使用的ASP.NET MVC书中如何处理Action Methods有一个非常好的解释。碰巧,相关页面可在Google图书上找到:
如果链接死亡,它是Steven Sanderson的Pro ASP.NET MVC框架的第310页。
不确定它是否会帮助您弄清楚如何编写单元测试,但它可能会帮助您遵循Reflector代码......