c# - una - ¿Cómo devolver la vista parcial de otro controlador por controlador?
redireccionar mvc 5 (3)
Tengo un archivo XXX.cshtml
en una carpeta Views/ABC
. Su controlador es ABC
También tengo un método de acción en mi controlador DEF
que devuelve una vista Partialview("XXX" , xyzmodel)
Aparece un error de "vista no encontrada".
Cómo llamar a esa vista desde otro controlador
El control busca una vista en el siguiente orden:
- Primero en la carpeta compartida
- Luego, en la carpeta que coincide con el controlador actual (en su caso, es Views / DEF)
Como no tiene xxx.cshtml
en esas ubicaciones, devuelve un error de "vista no encontrada".
Solución: puede usar la ruta completa de su vista:
Me gusta
PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
Normalmente, las vistas pertenecen a un controlador de coincidencia específico que admite sus requisitos de datos, o la vista pertenece a la carpeta Views/Shared
si se comparte entre los controladores (de ahí el nombre).
"Respuesta" (pero no recomendado - vea abajo):
Puede hacer referencia a vistas / vistas parciales desde otro controlador, especificando la ruta completa (incluida la extensión) como:
return PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
o una ruta relativa (sin extensión), basada en la respuesta de @Max Toro
return PartialView("../ABC/XXX", zyxmodel);
PERO ESTO NO ES UNA BUENA IDEA DE CUALQUIER FORMA
* Nota: Estas son las dos únicas sintaxis que funcionan . no ABC//XXX
o ABC/XXX
o cualquier otra variación, ya que todas son rutas relativas y no encuentran una coincidencia.
Mejores alternativas:
Puede usar Html.Renderpartial
en su vista, pero también requiere la extensión:
Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", modeldata);
Use @Html.Partial
para la sintaxis de Razor en línea:
@Html.Partial("~/Views/ControllerName/ViewName.cshtml", modeldata)
Puede usar la sintaxis de ../controller/view
sin extensión (de nuevo crédito a @Max Toro):
@Html.Partial("../ControllerName/ViewName", modeldata)
Nota: Aparentemente RenderPartial
es ligeramente más rápido que Parcial, pero eso no es importante.
Si realmente quiere llamar al otro controlador, use:
@Html.Action("action", "controller", parameters)
Solución recomendada: @ Html.Action
Mi preferencia personal es usar @Html.Action
ya que permite que cada controlador administre sus propias vistas, en lugar de referencias cruzadas de otros controladores (lo que lleva a un gran desorden tipo spaghetti).
Normalmente, solo aprobará los valores clave requeridos (como cualquier otra vista), por ejemplo, para su ejemplo:
@Html.Action("XXX", "ABC", new {id = model.xyzId })
Esto ejecutará la acción ABC.XXX
y representará el resultado en el lugar. Esto permite que las vistas y los controladores permanezcan separados por sí mismos (es decir, reutilizables).
Actualización Sep 2014:
Acabo de llegar a una situación en la que no pude usar @ Html.Action, pero necesitaba crear una ruta de vista basada en una action
y nombres de controller
. Con ese fin agregué este sencillo método de extensión View
a UrlHelper
para que pueda decir return PartialView(Url.View("actionName", "controllerName"), modelData)
:
public static class UrlHelperExtension
{
/// <summary>
/// Return a view path based on an action name and controller name
/// </summary>
/// <param name="url">Context for extension method</param>
/// <param name="action">Action name</param>
/// <param name="controller">Controller name</param>
/// <returns>A string in the form "~/views/{controller}/{action}.cshtml</returns>
public static string View(this UrlHelper url, string action, string controller)
{
return string.Format("~/Views/{1}/{0}.cshtml", action, controller);
}
}
Simplemente podrías usar:
PartialView("../ABC/XXX")