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?

dtc
fuente

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.

womp
fuente
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.

Guillaume86
fuente
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");
doncadavona
fuente
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?

Paul Johnson
fuente
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" });
ignacio chiazzo
fuente
¿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 ...

Marko
fuente
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);
Yair GR
fuente
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