何时使用JsonResult而不是ActionResult

我一直无法找到关于这个问题的具体答案。 我已经查看了这个问题以及其他地方的post和后续post,但我真正读到的只是JsonResult有一个硬编码的内容类型,并且确实没有任何性能提升。

如果两个结果都可以返回Json,为什么需要在ActionResult上使用JsonResult。

public ActionResult() { return Json(foo) } public JsonResult() { return Json(bar) } 

任何人都可以解释ActionResult无法完成工作并且必须使用JsonResult的情况。 如果没有,为什么JsonResult首先存在。

何时使用JsonResult不是ActionResult

我通常会返回具体的结果(例如JsonResultViewResult ),还有我的专业人士:

  • Controller的界面提供了有关其行为的更多信息。 当您将PartialViewResultViewResult精确指定为结果类型时,使用部分或共享视图会更容易。
  • 它更容易测试,因为在unit testing中不需要将结果转换为具体类型 。

人们支持这种方法有一些链接:

  • ActionResult和ViewResult for action方法有什么区别?
  • ASP.NET MVC控制器方法必须返回ActionResult吗?
  • ViewResult vs ActionResult

Pro ASP.NET MVC 3框架引用了一句话:

注意请注意,列表中action方法的返回类型是ViewResult 。 如果我们指定了更通用的ActionResult类型,那么该方法也可以编译和工作。 实际上,一些MVC程序员会将每个动作方法的结果定义为ActionResult ,即使他们知道它总会返回更具体的类型。 我们在下面的示例中特别勤奋地阐述了如何使用每种结果类型,但我们在实际项目中往往更加放松。

只有当一个动作应该返回不同类型的结果时,我才会使用ActionResult不是具体的一个。 但这不是常见的情况。

我还想补充一点, ActionResult是一个抽象类,所以你不能简单地创建这种类型的实例并返回它。 JsonResult是具体的,因此您可以创建其实例并从操作方法返回。 还有许多其他类型派生自ActionResult ,基本上所有这些类型都用于覆盖ExecuteResult方法 。

 public abstract class ActionResult { public abstract void ExecuteResult(ControllerContext context); } 

ControllerActionInvoker调用此方法,并实现将数据写入response对象的逻辑。

ControllerActionInvoker不知道具体结果,因此它可以处理从ActionResult派生的任何结果并实现ExecuteResult

在这两种情况下,您在示例中返回JsonResult类型的实例,而Json(model)它只是一个创建JsonResult实例的Factory方法。

还有另一个问题是,方法的数据类型是否尽可能具体或更一般? 讨论了方法参数和返回值的最佳实践

一般的想法提供抽象类型作为参数,以便您的方法可以处理更广泛的参数; 返回具体足够的类型,以便您的客户不需要转换或转换它们。

您可能已经注意到MVC控制器中所有常见返回类型的名称以“result”结尾,并且通常,大多数操作都返回ActionResult。 如果查看文档 ,可以看到几个更加特定的结果类型inheritance自抽象类ActionResult。 因此,您现在可以在所有操作中返回ActionResult,甚至返回不同的类型。 例:

 public ActionResult View(int id) { var result = _repository.Find(id); if(result == null) return HttpNotFound(); //HttpNotFoundResult, which inherits from HttpStatusCodeResult return View(result); //ViewResult } 

所有这些都可以根据请求更轻松地返回不同的内容。 那你为什么要在ActionResult上使用JsonResult呢? 也许所以没有误解,你确实只能返回JSON,可能是为了可读性,或者其他一些个人偏好。

它只是坚持简单的多态性原理。

通过将方法签名定义为返回抽象ActionResult ,它是JsonResultViewResultContentResult (和其他)的基类型,您可以通过让操作的实现决定返回哪个ActionResult来返回上述任何类型。 。

例如:

 public ActionResult GetData(int id) { var data = .... // some data if (Request.AcceptTypes.Contains("json")) return Json(data); else return View(data); } 

实际上,在OOP中将方法的返回类型定义为尽可能抽象。 您也可以在.NET BCL中找到它,例如Linq中的IEnumerable<>用法:

 public static IEnumerable Where ( this IEnumerable source, Func predicate ); 

Where()方法被声明为返回IEnumerable因此您可以在任何实现IEnumerable接口的类型上调用该方法,无论是ArrayListHashSet还是Dictionary

实际上没有理由使用JsonResult作为Action方法的返回类型。 在这种情况下,最好使用抽象类ActionResult来遵循多态原则。

通过调用return Json(value)您实际上调用了Controller类的辅助方法,它看起来像:

 protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; } 

正如我们所看到的 – Json helper方法无论如何都会实例化JsonResult