【问题标题】:Why does most MVC sample controller code return ActionResult?为什么大多数 MVC 示例控制器代码都返回 ActionResult?
【发布时间】:2011-06-04 18:06:27
【问题描述】:

只是想知道为什么我在示例 MVC 代码中看到的几乎每个控制器方法都返回 ActionResult,即使很明显代码只能返回一种类型的结果。我知道在某些情况下这是有保证的,因为您可能会根据逻辑返回,例如 RedirectResult 或 ViewResult,但对于我见过的大多数方法而言,情况并非如此。

这不就等于在方法上有一个'object'的返回类型吗?为什么不直接指定 JsonResult、FileResult 或 ViewResult 作为返回类型呢?在每个控制器方法上将返回类型设置为 ActionResult 是否有我没有看到的好处?

经典例子:

public ActionResult Index()
{
    return View();
}

为什么这似乎是常态而不是这个:

public ViewResult Index()
{
    return View();
}

编辑: 到目前为止,除了一个之外的所有响应都表明 ActionResult 更通用。我知道那么多。 :) 为什么这种在控制器方法上被接受的做法,而不是在其他任何地方?您不仅可以在普通方法上返回类型的最高级别基类,还尝试返回通常可以返回的最具体的类型。是什么让控制器方法如此不同,以至于博主和“示例代码编写者”(是的,我提出了这个术语)只会诉诸于返回 ActionResult?

【问题讨论】:

标签: asp.net-mvc


【解决方案1】:

从此处接受的答案中逐字引用 SO。对我来说很有意义:

Must ASP.NET MVC Controller Methods Return ActionResult?

你绝对可以使用特定的回报 类型,即使大多数示例 网络似乎返回 动作结果。唯一一次我会 返回 ActionResult 类是什么时候 动作方法的不同路径 返回不同的子类型。

史蒂文·桑德森也推荐 在他的书中返回特定类型 Pro ASP.NET MVC Framework。看一看 在下面的报价:

"这个动作方法具体 声明它返回一个实例 的视图结果。它只会工作 如果方法返回类型相同 是 ActionResult(的基类 所有行动结果)。事实上,有些 ASP.NET MVC 程序员声明所有 他们的动作方法返回一个 非特定的 ActionResult,即使它们 确定它会永远 返回一个特定的子类。 然而,这是一个成熟的 面向对象原理 方法应该返回的编程 他们能做到的最具体的类型(如 以及接受最普遍的 他们可以的参数类型)。下列的 这一原则最大限度地提高了便利性 和调用代码的灵活性 你的方法,比如你的单元测试。"

另见:

http://www.bengtbe.com/blog/post/2009/07/01/Use-specific-return-types-in-your-ASPNET-MVC-action-methods.aspx

【讨论】:

  • 对我来说也很有意义,我会接受这个作为答案,但我仍然很好奇为什么在开发人员习惯于尽可能具体地声明返回类型的环境中,突然之间,MVC 程序员似乎只是在一个特定实例中抛出了这个概念。没有多大意义。
  • @Scott Schluer:因为控制器操作的真正“消费代码”通常是浏览器或 javascript,所以类型安全的好处在这个特定实例中不太明显。如果您可以像设置 GWT 的 RPC 框架那样以类型安全的语言使用此代码,我认为人们会更加认真地设置特定的返回类型。
  • 我发现对所有这些都使用 ActionResult 非常方便。我同意减少类型安全问题使得在这种特定情况下更合适。我认为这是一种主要为了方便和可读性而衍生的做法。当我看到 ActionReult 时,我立即知道该方法的目的是什么。如果我需要对该操作进行重定向,则无需修改返回类型即可。
  • @Derrick Bingo 关于重定向。 @jim Derrick 所说的 - 如果您需要重定向而不是显示页面,则需要更改返回类型。
  • bzlm - 在这方面肯定被接受。但是,在这种情况下,返回类型可能会在更改后“提升”。
【解决方案2】:

我的猜测是返回 ActionResult 而不是更具体的结果,这仅仅是因为不需要使代码更具体。

使用更通用的类型可以让事情更灵活。

请记住,更改返回类型在 Web 应用程序项目中可能不是问题,但它也会导致您更改测试项目中的所有单元测试。

【讨论】:

  • 在我看来,如果您更改要返回的内容,则无论如何都必须更改单元测试以反映该更改。当这种情况发生时,我宁愿让编译器告诉我“这些单元测试不再起作用”。在大多数情况下,您的单元测试只需要将结果转换为其实际类型,以便测试,例如,返回的 ViewResult 上的模型是否具有您期望的值。
  • @StriplingWarrior - 就个人而言,我宁愿能够构建我的项目,然后发现我的单元测试现在失败了,而不是因为代码损坏而不得不暂停我的项目的构建单元测试。
  • 我想这是一个见仁见智的问题。我个人认为在编译时发现更多问题可以节省时间,这是使用类型安全的编译语言的最大原因之一。
【解决方案3】:

这可能是因为 ActionResult 是视图可以处理的最高对象。

ActionResult

ViewResult

System.Object
  System.Web.Mvc.ActionResult
    System.Web.Mvc.ViewResultBase
      System.Web.Mvc.ViewResult

对我来说,每个 XXXResult 都专门用于特定用途。 如果不需要具体...

【讨论】:

    【解决方案4】:

    只有当您不确定控制器内部逻辑的返回类型是什么时,您才应该使用通用返回类型。否则 - 使用特定的(它被认为是 BETTER 编程)。

    我不知道为什么人们在示例中使用 ActionResult,但我在示例中看到了很多我可能不同意的东西 - 把好的东西留在那里......

    恕我直言 - 当您知道这是您使用的唯一返回对象而不是 ActionResults 时,您应该使用 ViewResult。

    【讨论】:

      【解决方案5】:

      我认为真正的原因是 MVC 模板中的自动生成代码以 ActionResult 开始,而人们只是遵循该模式。由于许多人不会对他们的控制器操作进行单元测试,因此他们不会以类型安全的方式使用结果,这会使这成为一个痛点。

      【讨论】:

      • 这看起来很疯狂。查看weblogs.asp.net/scottgu/archive/2010/07/27/…。甚至 Scott Guthrie 也这样做了,我敢肯定他不是那种会因为缺乏理解而仅仅遵循开箱即用的开发人员的人。 :) 一个简单的控制器方法,只返回一个视图,但返回类型是 ActionResult...
      【解决方案6】:

      ScottGu 这样做是出于同样的原因;展示一个例子更容易。演示的主题通常决定了您看到的 ode 质量;如果只是为了示例,他们通常会抛出一些东西来说明一个观点(他们让自己很容易在他们结束 b4 发布时编写/测试示例,并且在发布时就这样离开了;我已经这样做了)。就最佳实践而言;关于 HTML 和 JS(本质上)“不关心”类型,不要让 JavaScript 的问题(如类型弱点)泄漏/感染你自己磨练的良好编码风格。尽可能使用特定类型。另外,你的 JS 代码也很可能期待 JSON 结果(如果它是使用键入最佳实践进行编码的),并且代码也可以测试,所以如果它正在尝试,不想把 JS 代码绑在那里在可能的类型上做正确的事情。诚然,在某些情况下,不利影响比其他情况更明显/更不明显(比如返回到类型安全性较低的语言),这只是一个更好的编程习惯,保持一致。一般来说,做这种事情通常会导致某种类型转换/强制以返回到您想要在返回时使用的更具体的对象的功能(这很可能在基础对象中不可用 - 如果它总是如此,那么您的类型太具体/无论如何都应该是基础)。铸造本质上是丑陋/邪恶的;在运行时派生类型总是会给您带来麻烦(为什么不鼓励这种做法/静态/强类型/安全性的好处几十年来)。让代码的使用者/维护者也能够通过元信息(将鼠标悬停在方法上等)辨别函数实际在做什么/返回。事实上,单元测试更好,因为这是可以测试的条件(正如 Steven Sanderson 书中的摘录所暗示的那样)。我是否抓住了一个人以不想持有构建作为弱类型的理由?真的吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-04
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-06
        • 1970-01-01
        相关资源
        最近更新 更多