我一直无法找到关于这个问题的具体答案。我已经查看了来自this问题和其他地方的帖子和后续帖子,但我真正读到的只是JsonResult有一个硬编码的内容类型,并且确实没有任何性能提升。
如果两个结果都可以返回Json,为什么需要在ActionResult上使用JsonResult。
public ActionResult()
{
return Json(foo)
}
public JsonResult()
{
return Json(bar)
}
任何人都可以解释一下ActionResult无法完成工作并且必须使用JSONResult 的情况。如果没有,为什么JsonResult首先存在。
答案 0 :(得分:18)
何时使用
JsonResult
而不是ActionResult
我通常会返回具体结果(例如JsonResult
,ViewResult
),还有我的专业人士:
PartialViewResult
和ViewResult
作为结果类型时,使用部分或共享视图会更容易。人们支持这种方法有一些链接:
引用Pro ASP.NET MVC 3 Framework:
注意请注意,该操作方法的返回类型 列表为
ViewResult
。该方法也可以编译和工作 如果我们指定了更通用的ActionResult
类型。其实有些 MVC程序员将每个动作方法的结果定义为ActionResult
,即使他们知道它总会返回更多 具体类型。我们在这种做法中特别勤奋 以下示例说明如何使用每个结果 类型,但我们往往在实际项目中更放松。
只有当一个动作应该返回不同类型的结果时,我才会使用ActionResult
而不是具体的。但这不是常见的情况。
我还想补充说ActionResult
是一个抽象类,所以你不能简单地创建这种类型的实例并返回它。 JsonResult
是具体的,因此您可以创建其实例并从操作方法返回。 There are many other types that derived from ActionResult
基本上所有这些都是used to override ExecuteResult
method。
public abstract class ActionResult
{
public abstract void ExecuteResult(ControllerContext context);
}
此方法由ControllerActionInvoker
调用,并实现将数据写入response
对象的逻辑。
ControllerActionInvoker
不知道具体结果,因此可以处理从ActionResult
派生的任何结果并实现ExecuteResult
在这两种情况下,您都会在示例中返回JsonResult
类型的实例,Json(model)
它只是一个创建JsonResult
实例的工厂方法。
还有另一个 SO问题Is it better to have a method's datatype be as specific as possible or more general?,其中讨论了方法参数和返回值的最佳做法。
一般的想法是提供抽象类型作为参数,以便您的方法可以处理更广泛的参数; 返回足够多的类型,以便您的客户无需转换或转换它们。
答案 1 :(得分:4)
您可能已经注意到MVC控制器中所有常见返回类型的名称以" result"结尾,并且通常,大多数操作都会返回ActionResult。如果查看documentation,可以看到几个更加特定的结果类型继承自抽象类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,可能是为了可读性,或者其他一些个人偏好。
答案 2 :(得分:3)
它只是遵循简单的多态原则。
通过将方法签名定义为返回抽象ActionResult
,它是JsonResult
,ViewResult
,ContentResult
(和其他)的基本类型,您将获得通过让操作的实现决定返回哪个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<T> Where<T>
(
this IEnumerable<T> source,
Func<T, bool> predicate
);
Where()
方法被声明为返回IEnumerable<T>
,因此您可以在实现IEnumerable<T>
接口的任何类型上调用该方法,无论是Array
,{ {1}},List
或HashSet
。
答案 3 :(得分:2)
实际上没有理由使用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
辅助方法无论如何都会实例化JsonResult
。