【问题标题】:Must ASP.NET MVC Controller Methods Return ActionResult?ASP.NET MVC 控制器方法必须返回 ActionResult 吗?
【发布时间】:2010-11-04 12:40:05
【问题描述】:

作为 ASP.NET MVC 的新手,我一直想知道 Controller 方法的签名。在我见过的所有示例中,它们似乎总是返回 ActionResult,即使它们实际上返回 ViewResult 实例或类似实例。

这是一个常见的例子:

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

在这种情况下,将方法声明为public ViewResult Index() 并获得更强的类型支持不是更有意义吗?

实验表明这是可行的,所以它似乎是可能的。

我确实意识到可能存在需要多态性的情况(例如,如果您只想在某些情况下重定向,但在其他情况下显示视图),但如果方法 always 返回视图,我会发现 ViewResult 更可取。

就未来的兼容性而言,ActionResult 显然提供了更健壮的签名,但如果一个人控制了整个代码库,那么如果将来需要的话,总是可以将方法的签名更改为更通用的返回类型。

是否还有其他我不知道的注意事项,或者我应该继续使用特定的返回类型声明我的控制器方法?

【问题讨论】:

    标签: asp.net-mvc polymorphism actionresult viewresult


    【解决方案1】:

    您绝对可以使用特定的返回类型,尽管网络上的大多数示例似乎都返回 ActionResult。我唯一会返回 ActionResult 类的情况是 action 方法的不同路径返回不同的子类型。

    Steven Sanderson 还建议在他的书 Pro ASP.NET MVC Framework 中返回特定类型。看看下面的报价:

    这个动作方法特别声明它返回一个 ViewResult 的实例。如果改为该方法,它的工作原理是一样的 返回类型是 ActionResult(所有操作结果的基类)。 事实上,一些 ASP.NET MVC 程序员声明了他们所有的动作方法 作为返回一个非特定的 ActionResult,即使他们肯定知道 它将始终返回一个特定的子类。然而,这是一个 面向对象编程中公认的原则,即方法 应该返回他们可以返回的最具体的类型(以及接受 他们可以使用的最通用的参数类型)。遵循这个原则 最大限度地提高调用您的方法的代码的便利性和灵活性, 比如你的单元测试。

    【讨论】:

    • 在编写路由、过滤器或其他跨控制器操作执行逻辑的功能时,具体说明控制器结果是有好处的,因为您可以轻松确定控制器操作是否返回 JSON、视图等,而无需运行它。
    【解决方案2】:

    始终返回您可以返回的最准确的类型。因此,当操作始终显示视图时,您应该返回 ViewResult。我只会在某些情况下(无效的发布数据)或 RedirectToRouteResult 在其他情况下返回 ViewResult 时使用 ActionResult 。

    使用一些高级动作过滤器/执行场景,您甚至可以返回与 ActionResult 无关的完全不同的东西。

    【讨论】:

      【解决方案3】:

      [部分答案]:您并不总是返回 ActionResult,不。以下是您可以返回的一些其他结果的列表:

      • 查看结果
      • 部分查看结果
      • 重定向结果
      • RedirectToRouteResult
      • 内容结果
      • JsonResult
      • JavaScriptResult
      • 文件结果
      • 空结果

      请参阅docs 了解更多信息。

      也许这会有所帮助。祝你好运!

      【讨论】:

      • 都是从ActionResult派生出来的……他说的是方法的返回类型。
      【解决方案4】:

      是的,您可以像这样定义您的操作:public ViewResult Index()。但有时您的操作可能会返回不同的结果(如果不将结果声明为基础ActionResult 类是不可能的)。例如:

      public ActionResult Show()
      {
          ...
      
          if(Request.IsAjaxRequest())
          {
              return PartialView(...);
          }
      
          return View(...);
      }
      

      或:

      public ActionResult Show()
      {
          ...
      
          try
          {
              ...
          }
          catch(Exception)
          {
              return RedirectToAction(...);
          }
      
          return View(...);
      }
      

      【讨论】:

      • 我必须同意这一点。某些操作类型根据各种条件返回重定向或返回视图是很常见的(当数据无效时编辑 POST 返回视图或在更新数据成功时重定向到另一个页面)。
      【解决方案5】:

      ActionResult 是各种返回类型的基类。因此,您的操作必须返回一个 ActionResult 或从它派生的类才能工作。常见的有ViewResultJsonResult等。

      【讨论】:

        【解决方案6】:

        是的,我有 Sanderson 的书,我喜欢关于具体的部分,因为当我查看其他控制器动作示例时,这让我很烦恼。我的哲学甚至 b4 学习 MVC 是,因为函数(返回值的方法)应该被视为好像你在声明一个变量/可以在上下文中替换相同类型的变量/引用,所以要具体说明类型,因为你如果声明一个 var (将其视为希望避免在应用程序中将所有变量定义为“对象”类型 - 更健壮,但您会失去一些设计时检查和类型安全性)。也有助于正确返回类型的控制器单元测试。

        有关相关参考,请查看 Listkov 的替换原则(“SOLID”中的“L”)。

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 2010-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-25
          • 1970-01-01
          • 2014-04-15
          相关资源
          最近更新 更多