ViewResult()和ActionResult()之间的区别


294

ViewResult()ActionResult()ASP.NET MVC 和有什么不一样?

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

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

11
好问题。我观看了一个视频,并创建了单元测试,教师首先将他要测试的Action的返回类型从ActionResult更改为ViewResult。没有解释...。我就像“我们可以随机改变类型吗?没有解释”
Doug Chamberlain 2012年

3
这大概文档是有帮助:) msdn.microsoft.com/en-us/library/...
user3885927

Answers:


372

ActionResult是一个抽象类,可以有多个子类型。

ActionResult子类型

  • ViewResult-将指定的视图呈现到响应流

  • PartialViewResult-将指定的局部视图渲染到响应流

  • EmptyResult-返回空响应

  • RedirectResult-执行HTTP重定向到指定的URL

  • RedirectToRouteResult-根据给定的路由数据执行HTTP重定向到由路由引擎确定的URL

  • JsonResult-将给定的ViewData对象序列化为 JSON格式

  • JavaScriptResult-返回一段可以在客户端上执行的JavaScript代码

  • ContentResult-将内容写入响应流而无需查看

  • FileContentResult-将文件返回给客户端

  • FileStreamResult-将文件返回给客户端,该文件由Stream提供

  • FilePathResult-将文件返回给客户端

资源资源


5
返回ViewResult而不是ActionResult的好处是什么-它只是有点语义并显示您的意图-但实际上通常没有什么区别?
niico

120

ActionResult是一个抽象类。

ViewResult源自ActionResult。其他派生类包括JsonResultPartialViewResult

您以这种方式声明它,以便可以利用多态性并在同一方法中返回不同的类型。

例如:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}

2
这是否意味着我们应该始终返回ActionResult以便获得其优势。还是对此有任何限制或副作用?
Adarsh Kumar

5
@Adarsh-与C#中的任何抽象类相同。如果您想将实现封装在方法内部,或者希望将来对其他派生类型的API进行验证,则以这种方式声明。如果没有,请使用混凝土。我通常使用具体的示例(例如ViewResult或JsonResult)
RPM1984

31

出于同样的原因,您没有编写每个类的每个方法来返回“对象”。您应该尽可能具体。如果您打算编写单元测试,这特别有价值。没有更多的测试返回类型和/或强制转换结果。


根据我的经验,使用ViewResult的好处是代码和单元测试更加简洁。
JoshYates1980 '16

20

ViewResult是ActionResult的子类。View方法返回一个ViewResult。因此,实际上这两个代码段完全相同。唯一的区别是,使用ActionResult时,您的控制器不会承诺返回视图-您可以更改方法主体以有条件地返回RedirectResult或其他内容,而无需更改方法定义。



4

在Controller中,可以使用以下语法

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

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

在上面的示例中,仅返回类型有所不同。一个返回ViewResult,另一个返回ActionResult

ActionResult是一个抽象类。它可以接受:

ViewResult,PartialViewResult,EmptyResult,RedirectResult,RedirectToRouteResult,JsonResult,JavaScriptResult,ContentResult,FileContentResult,FileStreamResult,FilePathResult等。

ViewResult是的子类ActionResult


4
我不确定这是否意味着您的意思,但是以防万一,我想澄清一下您不能同时使用这两种方法,因为它们的名称和(无)参数是相同的。仅通过更改结果类型不可能重载方法。
安德鲁

0

在Controller中,我用ActionResult指定了以下代码,该代码是基类,可以在MVC中具有11个子类型,例如:ViewResult,PartialViewResult,EmptyResult,RedirectResult,RedirectToRouteResult,JsonResult,JavaScriptResult,ContentResult,FileContentResult,FileStreamResult,FilePathResult。

    public ActionResult Index()
                {
                    if (HttpContext.Session["LoggedInUser"] == null)
                    {
                        return RedirectToAction("Login", "Home");
                    }

                    else
                    {
                        return View(); // returns ViewResult
                    }

                }
//More Examples

    [HttpPost]
    public ActionResult Index(string Name)
    {
     ViewBag.Message = "Hello";
     return Redirect("Account/Login"); //returns RedirectResult
    }

    [HttpPost]
    public ActionResult Index(string Name)
    {
    return RedirectToRoute("RouteName"); // returns RedirectToRouteResult
    }

同样,我们可以使用ActionResult()返回所有这11个子类型,而无需显式指定每个子类型方法。如果要返回不同类型的视图,则ActionResult是最好的选择。


0

为了节省您的时间,以下是上一个答案中的链接的答案,网址为 https://forums.asp.net/t/1448398.aspx

ActionResult是一个抽象类,它是ViewResult类的基类。

在MVC框架中,它使用ActionResult类来引用您的操作方法返回的对象。并在其上调用ExecuteResult方法。

ViewResult是此抽象类的实现。它将尝试通过给定的视图名称在一些预定义的路径(/ views / controllername /,/ views / shared /等)中找到视图页面(通常是aspx页面)。

通常,让您的方法返回更具体的类是一个好习惯。因此,如果您确定操作方法将返回某些视图页面,则可以使用ViewResult。但是,如果您的操作方法可能具有不同的行为,例如渲染视图或执行重定向。您可以使用更通用的基类ActionResult作为返回类型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.