Mostrar una vista desde otro controlador en ASP.NET MVC


248

¿Es posible mostrar una vista desde otro controlador?

Digamos, por ejemplo, que tengo una CategoriesControllery una Category/NotFound.aspxvista. Mientras CategoriesControllerestoy en el , puedo regresar fácilmente View("NotFound").

Ahora digamos que tengo una ProductsControllery una acción y vista para agregar un producto. Sin embargo, esta acción requiere que tengamos una Categoría para agregar el Producto. Por ejemplo, Products/Add/?catid=10.

Si no puedo encontrar la Categoría basada en catid, quiero mostrar la NotFoundvista desde el controlador de Categorías en lugar de crear una CategoryNotFoundvista bajo el controlador de Productos.

¿Es esto posible o estoy estructurando las cosas de manera incorrecta? ¿Existe una forma correcta de hacer esto?

Respuestas:


283

Si. De manera predeterminada, ASP.NET MVC se registra primero \Views\[Controller_Dir]\, pero después de eso, si no encuentra la vista, se registra \Views\Shared.

El directorio compartido está allí específicamente para compartir vistas entre múltiples controladores. Simplemente agregue su Vista al subdirectorio Compartido y listo.

Si lo hace return View("~/Views/Wherever/SomeDir/MyView.aspx"), puede devolver cualquier Vista que desee.


Gracias, esto suena como la solución que debería estar usando. Sin embargo, todavía me pregunto si es posible mostrar una Vista desde otro controlador. ¿Supongo que esto viola alguna regla en MVC?
dtc

1
En la situación que describió anteriormente, sí, debería estar usando la carpeta Shared.
Jonathan Freeland

69
Sí, eso también es posible. Si devuelve la Vista ("~ / Views / Wherever / SomeDir / MyView.aspx") Puede devolver cualquier Vista que desee. Esto no viola ninguna regla en particular per se, sin embargo, ASP.Net MVC tiene que ver con la "convención sobre la configuración". En otras palabras, el marco está diseñado para funcionar automáticamente usando ciertas convenciones, y debe utilizarlo siempre que sea posible.
womp

1
Gracias por la explicacion. No sabía que Views podría llamarse así. El directorio compartido, por supuesto, funciona perfectamente :)
dtc

1
No estaba en un controlador, así que tuve que usarlo new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };y funcionó
Nacht

162

Puedes usar:

return View("../Category/NotFound", model);

Fue probado en ASP.NET MVC 3, pero también debería funcionar en ASP.NET MVC 2.


3
Funciona en MVC 2, y resultó ser la solución más limpia para una situación inusual con la que estoy lidiando.
Todd Menier

3
Resharper informará ese enlace como un error, pero aún funciona.
CodeMonkeyKing

1
@CodeMonkeyKing - Resharper 7 (en VS2012) identifica correctamente una ruta con el formato "~/Views/Category/NotFound.cshtml".
Richard Ev

Vale la pena señalar: esta solución funciona con modos de visualización, por ejemplo, si tenía una vista "/Category/NotFound.Mobile.cshtml".
BenWillkommen

55

Si es posible. Devuelve un RedirectToAction()método como este:

return RedirectToAction("ActionOrViewName", "ControllerName");

1
Creo que esto debería ir como RedirectToAction ("ActionOrView", "Controller", null) ya que de lo contrario el segundo parámetro es routeValues
Zoran P.

Pero en este caso, debe escribir la acción en el controlador, a diferencia de la solución View.
tobbenb3

@ tobbenb3 Esa es una solución mucho mejor en lugar de codificar un resultado. De cualquier manera, no deberías pasar una cadena de ruta.
Perustaja

34

¿Lo has intentado RedirectToAction?


1
Diría que este es el MVC para cualquiera que no quiera la vista en las carpetas compartidas, tenga en cuenta que para todas las demás soluciones (como el uso de rutas directas) cualquiera que intente re-factorizar las vistas no tendrá que tener en cuenta que también está siendo utilizada en otro controlador, lo que resulta en un comportamiento impredecible
halb yoel

44
¿Qué tal sin redirigir?
Luckyy

solución mucho mejor que mover la vista a carpetas compartidas
juFo

Esta solución requiere acción en el controlador, View (directPath) procesa la salida sin ninguna acción. Cuando agrega una acción, debe pensar en ocultarla del acceso directo a través de la URL, generará un paso en el historial del navegador, etc. Pero sí, es mi camino a seguir.
Jan Zahradník

3
RedirectToAction envía un código de respuesta 302 al navegador. Eso no es apropiado cuando intenta mostrar una página 404 no encontrada. Es decir, esta solución parece funcionar pero confundirá a los motores de búsqueda.
NightOwl888

20

Sí tu puedes. Devuelve una acción como esta:

return RedirectToAction("View", "Name of Controller");

Un ejemplo:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees");

Este enfoque llamará al método GET

También podría pasar valores a acciones como esta:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees", new {id = id.ToString(), viewtype = "extended" });

¿Cómo enviaría un objeto con este enfoque?
Djeroen

Echa un vistazo @Djeroen
ignacio chiazzo

55
No está devolviendo una vista, está llamando a una acción.
0014

Sobre todo fue útil para mí.
Anil Shrestha

5

También puede llamar a cualquier controlador desde JavaScript / jQuery . Supongamos que tiene un controlador que devuelve 404 o algún otro control / página de usuario. Luego, en alguna acción, desde su código de cliente, puede llamar a una dirección que activará su controlador y devolverá el resultado en formato HTML , su código de cliente puede tomar este resultado devuelto y colocarlo donde desee en su página ...


No sabía eso. Parece que es algo que podría usar en el futuro. Sí, mvc rocks :)
dtc

1

Con este código puede obtener cualquier controlador:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, 
controller);

Traducción: Con este código puede obtener cualquier controlador: [código], Saludos,
Robert Columbia,

3
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta.
Nic3500
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.