【问题标题】:MVC3 ActionName attribute, its behaviour and effectsMVC3 ActionName 属性,它的行为和效果
【发布时间】:2012-04-11 06:16:03
【问题描述】:

在阅读 mcv3 时,我遇到了一个名为 [ActionName] 的属性名称。它实际上为操作方法提供了一个新名称。我测试了一个让我思考的场景;内部是如何工作的。当我的控制器类中有以下两种操作方法时

[ActionName("Test")]
public ActionResult Index()
{
      return View();
}
[ActionName("Index")]
public ActionResult Test()
{
      return View();
}

我认为这会以某种无限循环结束,或者会给出一些模棱两可的异常。但同样的工作正常,当我给这个网址http://mysite:1234/mycontroller时调用第二种方法@

是什么让 MVC 引擎选择第二种方法而不是第一种?

知道为什么会这样吗?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-3 razor


    【解决方案1】:

    Phil Haack 有一个关于这个问题的帖子:How a method becomes an action

    简而言之:ControllerActionInvoker 使用反射来查找与操作名称匹配的方法。

    ActionNameAttribute 重新定义了方法的名称。

    还要注意,您的视图名称与 ActionName 匹配,而不是 MethodName:方法 Index 将搜索名称为“Test”的视图

    【讨论】:

    • 好的,很棒的帖子。从帖子中我得到的是,魔术师是 ControllerActionInvoker。这将从路由数据字典中读取数据(从键“action”)。它将获得一个字符串值。然后它会先搜索 ActionName 再搜索 Method Name。
    • @thinkmmk 它不会寻找方法,它会寻找action。不使用 ActionNameAttribute 会导致:method = action
    • @AndrewF 如果我的方法没有任何 ActionName 属性,那么我猜 ControllerActionInvoker 将通过我的控制器类中的反射来查找方法名称。或者如果不存在,mvc 是否会自行放置动作名称属性?
    • @thinkmmk 是的。 By default, the ControllerActionInvoker uses reflection to find a public method on a class that derives from Controller which has the same name (case insensitive) as the current action.
    【解决方案2】:

    这就是Routing engine 的魔力。在 global.asax.cs 文件中的某处会定义路由模式,大部分默认为

     routes.MapRoute(
              "Default",                                              // Route name
              "{controller}/{action}/{id}",                           // URL with parameters
              new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
              );
    

    这是为您的应用程序定义的路由模式。动作名称属性映射到参数集合中的“动作”参数(MapRoute 的第三个参数)。

    在您的情况下,如果您将操作“索引”映射到方法“测试”。它应该调用 Test() 方法。我不确定它是否仍在为您调用 Index()。事实上,如果路由引擎在你的公共方法上找到 ActionName 属性,它并不关心方法名称。

    【讨论】:

    • 嗨 Chandermani,谢谢,是的,我的 global.asax 文件中有上述行。我编辑了我的问题,是的,它调用了 Test() 方法。所以我从你的解释中了解到,这就是路由引擎的魔力。如果发现重复名称,它将优先考虑 ActionName 属性而不是实际的方法名称。还有一件事,这个决定发生在哪里,即在生命周期的路由阶段或控制操作阶段?
    • 如果你看一下路由 new { controller = "Home", action = "Index", id = "" }。路由引擎决定控制器、动作(因此是控制器上的方法),然后将控制权传递给控制器​​方法。
    【解决方案3】:

    ActionNameAttribute 它表示一个用于操作名称的属性。如果不存在,则使用方法的名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2012-04-17
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多