何时使用JsonResult而不是ActionResult

时间:2014-10-15 19:46:14

标签: c# asp.net-mvc json asp.net-mvc-4 return-value

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

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

public ActionResult()
{
    return Json(foo)
}

public JsonResult()
{
    return Json(bar)
}

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

4 个答案:

答案 0 :(得分:18)

  

何时使用JsonResult而不是ActionResult

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

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

引用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,它是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<T> Where<T>
                       (
                       this IEnumerable<T> source,
                       Func<T, bool> predicate
                       );

Where()方法被声明为返回IEnumerable<T>,因此您可以在实现IEnumerable<T>接口的任何类型上调用该方法,无论是Array,{ {1}},ListHashSet

答案 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