J'ai un fichier XXX.cshtml
dans un dossier Views\ABC
. Son contrôleur est ABC
J'ai aussi une méthode d'action dans mon contrôleur DEF
qui renvoie un Partialview("XXX" , xyzmodel)
Je reçois une erreur "vue non trouvée".
Comment appeler ça view depuis un autre contrôleur
Normalement, les vues appartiennent à un contrôleur spécifique correspondant qui prend en charge la configuration requise, ou la vue appartient au dossier Views/Shared
si elle est partagée entre plusieurs contrôleurs ( d'où le nom).
Vous pouvez vous référer à des vues/vues partielles d’un autre contrôleur, en spécifiant le chemin complet (y compris l’extension) comme:
return PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
ou un chemin relatif (sans extension), basé sur la réponse de @Max Toro
return PartialView("../ABC/XXX", zyxmodel);
MAIS CEC IS PAS UN BIEN IDEA TOUJOURS
* Remarque: Ce sont les deux seules syntaxes qui fonctionnent . not ABC\\XXX
ou ABC/XXX
ou toute autre variante, car ces chemins sont tous relatifs et ne trouvent pas de correspondance.
Vous pouvez également utiliser Html.Renderpartial
dans votre vue, mais cela nécessite également l'extension:
Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", modeldata);
Utilisez @Html.Partial
pour la syntaxe Razor en ligne:
@Html.Partial("~/Views/ControllerName/ViewName.cshtml", modeldata)
Vous pouvez utiliser la syntaxe ../controller/view
sans extension (à nouveau crédit à @Max Toro):
@Html.Partial("../ControllerName/ViewName", modeldata)
Remarque: Apparemment, RenderPartial
est légèrement plus rapide que Partiel, mais ce n'est pas important.
Si vous voulez réellement appeler l’autre contrôleur, utilisez:
@Html.Action("action", "controller", parameters)
Ma préférence personnelle est d'utiliser @Html.Action
car cela permet à chaque contrôleur de gérer ses propres vues, plutôt que les vues de références croisées d'autres contrôleurs (ce qui conduit à un grand désordre ressemblant à des spaghettis).
Vous devez normalement transmettre uniquement les valeurs de clé requises (comme toute autre vue), par exemple. pour votre exemple:
@Html.Action("XXX", "ABC", new {id = model.xyzId })
Ceci exécutera l'action ABC.XXX
et rendra le résultat sur place. Cela permet aux vues et aux contrôleurs de rester séparément autonomes (c'est-à-dire réutilisables).
Je viens de frapper une situation où je ne pouvais pas utiliser @ Html.Action, mais que je devais créer un chemin de vue basé sur un nom action
et controller
. À cette fin, j'ai ajouté cette simple méthode d'extension View
à UrlHelper
afin que vous puissiez dire 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);
}
}
Le contrôle recherche une vue dans l'ordre suivant:
Comme vous n'avez pas xxx.cshtml
à ces emplacements, une erreur "view not found" est renvoyée.
Solution: Vous pouvez utiliser le chemin complet de votre vue:
Comme
PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
Vous pouvez simplement utiliser:
PartialView("../ABC/XXX")