Diferencia entre ViewResult () y ActionResult ()

295

¿Cuál es la diferencia entre ViewResult()y ActionResult()en ASP.NET MVC?

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

public ActionResult Index()
{
    return View();
}
Domnic
fuente
12
Gran pregunta Vi un video y para crear pruebas unitarias, el instructor primero cambió el tipo de retorno de la Acción que iba a probar de ActionResult a ViewResult. Sin explicación ... Pensé: "¿Qué podemos cambiar aleatoriamente de tipos? Sin explicación"
Doug Chamberlain
3
Probablemente esta documentación sea útil :) msdn.microsoft.com/en-us/library/…
user3885927

Respuestas:

372

ActionResult es una clase abstracta que puede tener varios subtipos.

Subtipos de ActionResult

  • ViewResult - Representa una vista especificada en la secuencia de respuesta

  • PartialViewResult - Representa una vista parcial especificada en la secuencia de respuesta

  • EmptyResult : se devuelve una respuesta vacía

  • RedirectResult : realiza una redirección HTTP a una URL especificada

  • RedirectToRouteResult : realiza una redirección HTTP a una URL determinada por el motor de enrutamiento, en función de los datos de ruta dados

  • JsonResult : serializa un objeto ViewData dado en formato JSON

  • JavaScriptResult : devuelve un fragmento de código JavaScript que se puede ejecutar en el cliente

  • ContentResult : escribe contenido en la secuencia de respuesta sin requerir una vista

  • FileContentResult - Devuelve un archivo al cliente

  • FileStreamResult - Devuelve un archivo al cliente, que es proporcionado por un Stream

  • FilePathResult - Devuelve un archivo al cliente

Recursos

Divi
fuente
55
¿Cuál es la ventaja de devolver ViewResult sobre ActionResult? ¿Es un poco más semántico y muestra su intención, pero en la práctica generalmente no hace la diferencia?
niico
121

ActionResult es una clase abstracta.

ViewResult deriva de ActionResult . Otras clases derivadas incluyen JsonResult y PartialViewResult .

Lo declaras de esta manera para que puedas aprovechar el polimorfismo y devolver diferentes tipos en el mismo método.

p.ej:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}
RPM1984
fuente
2
¿Significa que siempre debemos devolver ActionResult para que podamos aprovecharlo? ¿O hay alguna limitación o efecto secundario de esto?
Adarsh ​​Kumar
55
@Adarsh: es lo mismo con cualquier clase abstracta en C #. Declárelo de esa manera si desea encapsular la implementación dentro del método o si desea probar su API en el futuro para otros tipos derivados. Si no, use el concreto. Generalmente uso el concreto (por ejemplo, ViewResult o JsonResult)
RPM1984
31

Es por la misma razón por la que no escribe todos los métodos de cada clase para devolver "objeto". Debes ser lo más específico posible. Esto es especialmente valioso si planea escribir pruebas unitarias. No más pruebas de tipos de devolución y / o envío del resultado.

RickAndMSFT
fuente
El código más limpio y las pruebas unitarias son el beneficio de usar ViewResult según mi experiencia.
JoshYates1980
20

ViewResult es una subclase de ActionResult. El método View devuelve un ViewResult. Entonces, realmente estos dos fragmentos de código hacen exactamente lo mismo. La única diferencia es que con el ActionResult uno, su controlador no promete devolver una vista: puede cambiar el cuerpo del método para devolver condicionalmente un RedirectResult u otra cosa sin cambiar la definición del método.

Robert Levy
fuente
11

Si bien otras respuestas han notado las diferencias correctamente, tenga en cuenta que si de hecho está devolviendo un ViewResult solo, es mejor devolver el tipo más específico en lugar del tipo base de ActionResult. Una excepción obvia a este principio es cuando su método devuelve múltiples tipos derivados de ActionResult.

Para una discusión completa de las razones detrás de este principio, consulte la discusión relacionada aquí: ¿Deben los métodos del controlador ASP.NET MVC devolver ActionResult?

Zaid Masud
fuente
4

En el controlador, se podría usar la siguiente sintaxis

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

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

En el ejemplo anterior, solo varía el tipo de retorno. uno regresa ViewResultmientras que el otro regresaActionResult .

ActionResult es una clase abstracta. Puede aceptar:

ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePathResult, etc.

El ViewResultes una subclase de ActionResult.

ruchit
fuente
44
No estoy seguro de si esto es lo que quiso decir, pero en caso de que quiera aclarar que no puede tener esos dos métodos al mismo tiempo, ya que su nombre y (no) parámetros son los mismos. No es posible sobrecargar un método cambiando solo el tipo de resultado.
Andrew
0

En Controller, especifiqué el código siguiente con ActionResult, que es una clase base que puede tener 11 subtipos en MVC como: ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePtreamResult.

    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
    }

Del mismo modo, podemos devolver todos estos 11 subtipos usando ActionResult () sin especificar explícitamente cada método de subtipo. ActionResult es lo mejor si está devolviendo diferentes tipos de vistas.

Abhishek Duppati
fuente
0

Para ahorrarle tiempo, aquí está la respuesta de un enlace en una respuesta anterior en https://forums.asp.net/t/1448398.aspx

ActionResult es una clase abstracta, y es la clase base para la clase ViewResult.

En el marco MVC, utiliza la clase ActionResult para hacer referencia al objeto que devuelve su método de acción. E invoca el método ExecuteResult en él.

Y ViewResult es una implementación para esta clase abstracta. Intentará encontrar una página de vista (generalmente página aspx) en algunas rutas predefinidas (/ views / controllername /, / views / shared /, etc.) por el nombre de vista dado.

Por lo general, es una buena práctica hacer que su método devuelva una clase más específica. Entonces, si está seguro de que su método de acción devolverá alguna página de vista, puede usar ViewResult. Pero si su método de acción puede tener un comportamiento diferente, como representar una vista o realizar una redirección. Puede usar la clase base más general ActionResult como tipo de retorno.

wjxie
fuente