Cha*_*hah 13 asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 asp.net-mvc-4
我刚刚开始在MVC工作,我有一个疑问.
Nonaction
我们可以在控制器中创建私有方法,也可以在模型中编写方法并从控制器调用方法,而不是方法.
那么,NonAction
在MVC中使用公共方法的真正目的是什么?
(我重新组织了答案以更好地解决评论中的问题)
我认为,这个属性只是为了获得更好的灵活性.作为框架设计者,人们希望尽可能地放松最终用户的编码约束.没有公开不采取行动的要求听起来可能"一般",但对某些项目来说可能过于严格.添加[NonAction]
解决了他们的问题(尽管他们的设计很糟糕) - 显然你并没有被迫使用这个属性,所以从框架设计师的角度看它是双赢的.
另一个原因可能是遗留问题 - 在早期的MVC版本中,只有标记[Action]
为操作的方法.因此,当他们放宽要求(并且所有公共方法都被视为操作)时,他们保持[NonAction]
这样,以便开发人员不会太困惑.
一般来说,使用NonAction
是一种不好的做法 - 完全出于您所说的原因.如果某些事情不应该是一个行动,那么它不应该public
是第一位的.
控制器上的公共非操作方法的问题在于,它们使人们试图实例化控制器并调用方法,而不是分离出公共逻辑:
相比
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = new OrdersController().GetOrder(orderId); //GetOrder is public
...
}
}
Run Code Online (Sandbox Code Playgroud)
同
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = _orderService.GetOrder(orderId);
...
}
}
Run Code Online (Sandbox Code Playgroud)
第一种方法导致控制器与动作中非直接代码之间的耦合增加.代码变得难以遵循和重构,并且模拟/测试很麻烦.
除了增加耦合之外,任何公共非动作方法都是一个安全漏洞 - 如果你忘记用它来标记[NonAction]
(或者,更好的是,远离公众) - 因为它被视为正常动作并且可以在外部调用.我知道原来的问题有点意味着你肯定永远不会忘记在需要的时候附上属性,但是如果你愿意的话,理解会发生什么也是很重要的;)哦,好吧,我们就是这样,在我看来,与"忘记将方法设为私有"相比,"遗忘属性"在理论上更具可能性.
有时候人们说public
单元测试需要有非动作,但是当某些动作不是动作时,它很可能会在一个单独的类中被隔离并单独测试.此外,即使由于某种原因不可行,public
仅仅为测试目的标记方法是一种坏习惯 - 使用internal
并且InternalsVisibleTo
是推荐的方法.