vista tutorial paso mvc modelo form ejemplo controlador asp.net-mvc polymorphism actionresult viewresult

asp.net-mvc - tutorial - mvc c# windows forms ejemplo



¿Los métodos del controlador MVC de ASP.NET deben devolver el resultado de la acción? (6)

Siendo nuevo en ASP.NET MVC, me he estado preguntando sobre la firma de los métodos de controlador. En todos los ejemplos que he visto, siempre parecen devolver ActionResult, incluso si devuelven una instancia de ViewResult o similar.

Aquí hay un ejemplo comúnmente visto:

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

En tal caso, ¿no tendría más sentido declarar el método como public ViewResult Index() y obtener un mayor soporte de tipo?

La experimentación indica que esto funciona, por lo que parece posible.

Me doy cuenta de que puede haber situaciones en las que se desea el polimorfismo (por ejemplo, si desea redireccionar solo en ciertas situaciones, pero mostrar una vista en otras situaciones), pero si el método siempre devuelve una vista, encontraría una ViewResult más deseable.

En términos de compatibilidad futura, ActionResult obviamente proporciona una firma más robusta, pero si uno controla toda la base de códigos, siempre es posible cambiar la firma de un método a un tipo de devolución más general si eso fuera necesario en el futuro.

¿Hay alguna otra consideración de la que no tenga conocimiento, o debería seguir adelante y declarar mis métodos de control con tipos de devolución específicos?


ActionResult es la clase base para los distintos tipos de devolución. Por lo tanto, su acción debe devolver un ActionResult o una clase derivada de él para poder funcionar. Los más comunes son ViewResult , JsonResult , etc.


Sí, puede definir su acción como: public ViewResult Index() . Pero a veces su acción puede devolver resultados diferentes (es imposible sin declarar el resultado como clase ActionResult base). Por ejemplo:

public ActionResult Show() { ... if(Request.IsAjaxRequest()) { return PartialView(...); } return View(...); }

o:

public ActionResult Show() { ... try { ... } catch(Exception) { return RedirectToAction(...); } return View(...); }


Puede usar absolutamente tipos de devolución específicos, aunque la mayoría de los ejemplos en la web devuelvan el resultado de acción . La única vez que devolvería la clase ActionResult es cuando las diferentes rutas del método de acción devuelven diferentes subtipos.

Steven Sanderson también recomienda devolver tipos específicos en su libro Pro ASP.NET MVC Framework . Eche un vistazo a la cita a continuación:

"Este método de acción declara específicamente que devuelve una instancia de ViewResult. Sería igual si el tipo de retorno del método fuera ActionResult (la clase base para todos los resultados de acción). De hecho, algunos programadores MVC de ASP.NET declaran todos sus métodos de acción como devolver un ActionResult no específico, incluso si saben con certeza que siempre devolverá una subclase particular. Sin embargo, es un principio bien establecido en la programación orientada a objetos que los métodos deben devolver el tipo más específico que puedan (así como aceptando los tipos de parámetros más generales que puedan). Seguir este principio maximiza la conveniencia y flexibilidad para el código que llama a su método, como las pruebas de su unidad ".


Sí, tengo el libro de Sanderson, y me gustó esa parte acerca de ser específico, ya que eso era algo que me molestaba cuando miraba otros ejemplos de acción del controlador. Mi filosofía incluso b4 aprendiendo MVC era que las funciones (métodos que devuelven un valor) deberían tratarse como si estuvieras declarando una variable / ser sustituible en contexto para una variable / ref del mismo tipo, ser específico sobre el tipo, como tú si declarara una var (piense que quiere evitar la definición de todas sus variables como tipo "Objeto" en una aplicación), más robusto, pero pierde alguna verificación en tiempo de diseño y escribe seguridad. También facilita una prueba de unidad de controlador para el tipo de retorno correcto.

Para referencia relacionada, revise el Principio de Sustitución de Listkov (la "L" en "SOLIDO") también.



Siempre devuelva el tipo más preciso que puede devolver. Por lo tanto, debe devolver un ViewResult cuando la acción siempre muestre una vista. Solo usaría ActionResult cuando regrese en ViewResult en algunos casos (datos publicados no válidos) o RedirectToRouteResult en otros casos.

Con algunos escenarios avanzados de actionfilter / executing, incluso puede devolver cosas totalmente diferentes que no tienen nada que ver con ActionResult.